【发布时间】:2013-06-16 11:11:48
【问题描述】:
我正在学习编写更好的多线程程序、线程安全和确定性。我遇到了这段代码
// File Name : Callme.java
// This program uses a synchronized block.
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
// File Name : Caller.java
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
public Caller(Callme targ, String s) {
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
// synchronize calls to call()
public void run() {
synchronized(target) { // synchronized block
target.call(msg);
}
}
}
// File Name : Synch.java
public class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
// wait for threads to end
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
产生以下输出(尝试了大约 100 次)
[Hello]
[World]
[Synchronized]
所以我的第一个问题是,这个输出有保证吗?我还观察到,如果我将 sleep 更改为 100,它仍然会产生相同的输出,但如果我将 sleep 更改为 10输出更改为
[Hello]
[Synchronized]
[World]
第二个问题是,如果有保证,为什么?最后但并非最不重要的一点,为什么会有这个输出?我希望它是
[Hello]
[Synchronized]
[World]
【问题讨论】:
-
您需要先编辑 outputBuffer。然后冲洗它。
-
@huseyintugrulbuyukisik- outputBuffer?
-
您是否正在同步所有线程,例如:当第一个线程完成时,它会发出第二个要写入的信号。第二个完成并为第三个写单曲。
-
从
Runnable目标的构造函数启动线程是错误的。新线程可以在构造函数完成初始化对象之前开始执行run()方法。这条规则的更一般的表达是在构造函数返回之前,永远不要让另一个线程对另一个线程可见。
标签: java multithreading concurrency locking synchronized