我看过PingPong使用同步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();
}
}
}
通常,命中方法是不同步的,因为只有当有一个object.So时,同步关键字才能工作,结果可以是8-1 9-1 8-2 9-2或8-1 9-1 9-2 8-2 .(这是一个随机结果).But在本例中给出了所有时间8-1 8-2 9-1 9-1 9-2,这有点奇怪,因为这意味着命中方法是同步的!我已经修改了代码,以再次检查命中方法是否必须是sycnhron化的,所以我在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 + " ");
}
现在,代码在每次执行时都会给出随机结果。
我真的很困惑!!有人能帮我理解这个问题吗?
发布于 2015-02-09 04:36:04
您确实有两个独立的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()
。
发布于 2015-02-09 04:37:52
不确定同步是什么意思。是否意味着线程总是按照特定的顺序被线程调度程序拾取?如果是的话,那不是真的。只需将"i“从3增加到更高的值,例如10。我看到了以下输出:
12-1 11-1 12-1 12-2 11-2 12-3 11-3 11-4 11-4 12-5 11-5 11-6 11-6 12-6 11-7 12-8 12-9 11-8 11-9 11-911-9 11-9
嗯,我有多核处理器,因此在同一时间点有多个线程。我想对你来说也应该是这样。
https://stackoverflow.com/questions/28402769
复制相似问题