【发布时间】:2013-12-13 09:42:09
【问题描述】:
我从一本声称使用synchronized 将允许在同一实例上调用一个线程访问该方法的书中查看了一些关于线程/同步的简单示例。它确实按照承诺进行了序列化,但似乎在下面的 Synch main 方法中创建的第三个 Caller 大约是第二个之前的 9/10。此代码是显示没有同步方法的问题的示例代码。
class CallMe {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("CallMe Interrupted");
}
System.out.println("]");
}
}
class Caller implements Runnable {
String msg;
CallMe target;
Thread t;
public Caller (CallMe target, String msg) {
this.target = target;
this.msg = msg;
t = new Thread(this);
t.start();
}
@Override
public void run() {
target.call(msg);
}
}
class Synch {
public static void main(String args[]) {
CallMe target = new CallMe();
Caller c1 = new Caller(target, "Hello");
Caller c2 = new Caller(target, "Synchronized");
Caller c3 = new Caller(target, "World");
try {
c1.t.join();
c2.t.join();
c3.t.join();
} catch (InterruptedException e) {
System.out.println("Synch Interrupted");
}
}
}
本书展示了两种处理问题的方法,它们是 - synchronized void call(String msg) {...} 和 public void run() { synchronized (target) {...} }
很明显,这两个选项都有效,因为与原始代码相反,括号中的单词是一致的,例如...
[你好]
[世界](大约 90% 的时间调用是向后的)
[已同步](1/多个已同步为第一条消息)
...原始代码没有押韵或理由。所以我知道它正在“工作”并且可以通过在每个Caller 实例上放置断点来直接看到。它每次都有效,显然对我来说,当我这样做时。
为什么第三个Caller 在第二个之前一直调用call?
【问题讨论】:
标签: java multithreading synchronized