我有两个Java类,如下所示......
(1)JavaClass SyncTest:它定义一个类(实现Runnable)并调用Class SyncTestCalled中定义的“synchronized”方法(名为“call”)
(2)JavaClass SyncTestCalled:有一个同步方法。
------
After calling from main(), I am thinking it should output something like:
[Two]
[Three]
[One]
But, it outputs something like this (note the open bracket which is not paired in right locations) :
[[[Two]
Three]
One]
代码有什么问题?请帮忙。非常感谢!
Here is the code of these two classes...
public class SyncTest implements Runnable {
Thread t;
String name;
SyncTestCalled syncTestCalled;
public SyncTest(String name) {
t = new Thread(this, name);
syncTestCalled = new SyncTestCalled();
this.name = name;
t.start();
}
public void run() {
syncTestCalled.call(this.name);
}
public static void main(String[] args) {
SyncTest syncTest1 = new SyncTest("One");
SyncTest syncTest2 = new SyncTest("Two");
SyncTest syncTest3 = new SyncTest("Three");
}
} // of class SyncTest
public class SyncTestCalled {
public SyncTestCalled() {
// Do nothing
}
synchronized public void call(String message) {
System.out.print("[");
try {
Thread.sleep(1000);
System.out.print(message);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("]");
}
} // of class SyncTestCalled
答案 0 :(得分:3)
当您使用synchronized
作为方法声明的一部分时,Java会尝试获取调用该方法的对象上的监视器(锁定)。所以像
synchronized public void call(String message) {
...
}
相当于
public void call(String message) {
synchronized (this) {
...
}
}
在您的代码中,您创建三个不同的SyncTestCalled
对象,并将每个对象传递给不同的SyncTest
实例。换句话说,没有任何协调。每次致电
syncTestCalled.call(this.name);
在不同的对象上同步,因此没有线程需要等待其他对象。
由线程调度程序首先获得位置,因此您可以获得类似
的输出[[[Two]
Three]
One]
或
[[[OneThree]
Two]
]
请注意Thread.sleep(long)
不会放弃线程当前拥有的任何监视器。
答案 1 :(得分:0)
在任何给定时间,只有一个线程可以在给定实例上调用您的call()
方法。但是你想要的是几次调用System.out.print()
方法的原子性。为此,您需要获取System.out
上的锁定:
synchronized (System.out) {
System.out.print('[');
System.out.print(message);
System.out.println(']');
}
因为PrintStream
会锁定自身,这会阻止其他线程将自己的调用交错到print()
。