Java多线程调用同一方法导致相同输出时间值

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 现有程序同时启动了4个线程去调用TestDo.doSome(key, value)方法,由于TestDo.doSome(key, value)方法内的代码是先暂停1秒,然后再输出以秒为单位的当前时间值,所以,会打印出4个相同的时间值,如下所示:

回答:

在Java中,如果多个线程同时调用一个方法,并且该方法内部有一个暂停(如Thread.sleep(1000))的操作,那么在这段时间内,所有线程会在同一时刻开始执行,导致它们在暂停结束后同时输出相同的时间值。

以下是一个简单的示例代码,展示了如何实现这个场景:

public class TestDo {
    public void doSome(String key, String value) {
        try {
            // 暂停1秒
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 输出当前时间
        System.out.println("Key: " + key + ", Value: " + value + ", Time: " + System.currentTimeMillis() / 1000);
    }

    public static void main(String[] args) {
        TestDo testDo = new TestDo();
        
        // 创建4个线程
        for (int i = 0; i < 4; i++) {
            final int index = i;
            new Thread(() -> {
                testDo.doSome("key" + index, "value" + index);
            }).start();
        }
    }
}

在这个示例中,doSome方法会先暂停1秒,然后输出当前的时间。由于4个线程几乎同时启动,它们在1秒后会同时输出相同的时间值。

输出示例

假设程序在某一时刻运行,输出可能如下所示:

Key: key0, Value: value0, Time: 1699999999
Key: key1, Value: value1, Time: 1699999999
Key: key2, Value: value2, Time: 1699999999
Key: key3, Value: value3, Time: 1699999999

解决方案

如果希望每个线程输出不同的时间值,可以考虑在每个线程中引入不同的延迟,或者在输出时使用更精确的时间单位(如纳秒),但这通常不是解决问题的根本方法。更常见的做法是确保每个线程在执行时有不同的逻辑或状态,以便它们的输出能够反映出不同的时间或状态。