Java Thread Ping Pong 示例问题

Java Thread Ping Pong example Issue

我看过PingPong使用synchronized的例子keyword.Basicly实际例子是这样的:

public class PingPong implements Runnable {

    synchronized void hit(long n) throws InterruptedException {

        for (int i = 1; i < 3; i++)
            System.out.print(n + "-" + i + " ");
    }

    public static void main(String[] args) {
        new Thread(new PingPong()).start();
        new Thread(new PingPong()).start();
    }

    public void run() {
        try {
            Long id = Thread.currentThread().getId();

            hit(id);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

通常hit方法是不同步的,因为synchronized关键字只有在有一个时才会起作用object.So结果可能是8-1 9-1 8-2 9-2或8-1 9 -1 9-2 8-2...(这是一个随机结果)。但在这个例子中,它给了我们所有时间 8-1 8-2 9-1 9-2 这有点奇怪,因为这意味着hit 方法是同步的!!! 我修改了代码以再次检查命中方法必须不同步所以我在命中方法的开头添加了一个 Thread.sleep(1000) 它就像

synchronized void hit(long n) throws InterruptedException {
        Thread.sleep(1000);
        for (int i = 1; i < 3; i++)
            System.out.print(n + "-" + i + " ");
    }

现在每次执行时代码都会给出随机结果。

我真的越来越糊涂了!! 有人可以帮助我理解这个问题吗?

你确实有两个独立的 PingPong 实例,这意味着会有两个独立的监视器对象,这应该意味着线程不会被强制 运行 同步。

我认为您可能 运行正在关注线程调度行为。在单核 CPU 上,代码可能会按照您的描述很好地执行,因为线程调度程序永远不会有机会接管。

如果您在 for 循环中添加睡眠:

synchronized void hit(long n) throws InterruptedException {

    for (int i = 1; i < 3; i++){
        System.out.print(n + "-" + i + " ");
        Thread.sleep(0);
    }
}

那应该将调度程序释放给 运行 其他线程。请注意,JVM 不对调度程序的实际行为提供任何保证,但根据我的经验,以上内容就足够了。

如果您使用的是多核 CPU,我希望它能够在没有 sleep() 调用的情况下按预期工作。

不确定同步是什么意思。您的意思是线程调度程序总是以特定顺序接收线程吗?如果是,那不是真的。只需将 "i" 从 3 增加到更高的值,比如 10。我看到以下输出:

12-1 11-1 12-2 11-2 12-3 11-3 12-4 11-4 12-5 11-5 12-6 11-6 12-7 11-7 12-8 12-9 11-8 11-9

好吧,我有多核处理器,因此在同一时间点有多个线程。我想即使对你来说也应该如此。