我有几个关于 Java 线程的问题。这是代码:
TestingThread 类:
public class TestingThread implements Runnable {
Thread t;
volatile boolean pause = true;
String msg;
public TestingThread() {
t = new Thread(this, "Testing thread");
}
public void run() {
while (pause) {
//wait
}
System.out.println(msg);
}
public boolean isPause() {
return pause;
}
public void initMsg() {
msg = "Thread death";
}
public void setPause(boolean pause) {
this.pause = pause;
}
public void start() {
t.start();
}
}
和主线程类:
public class Main {
public static void main(String[] args) {
TestingThread testingThread = new TestingThread();
testingThread.start();
testingThread.initMsg();
testingThread.setPause(false);
}
}
问题列表:
t
应该是volatile
吗?msg
应该是volatile
吗?setPause()
应该同步吗?
- 这是良好线程结构的一个很好的例子吗?
最佳答案
您的问题 2 已经触及了相当微妙的地方。
在您非常具体的情况下,您:
- 首先从主线程写入
msg
; - 然后从主线程写入 volatile
暂停
; - 然后从子线程读取 volatile
pause
; - 然后从子线程读取
msg
。
因此,您已经在 msg
的写入和读取之间建立了一个happens-before关系。因此,msg
本身不必是 volatile 的。
然而,在现实生活中的代码中,您应该避免依赖这种微妙的行为:最好过度应用 volatile
并平静地 sleep 。
以下是 Java Language Specification 的一些相关引述:
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
If an action x synchronizes-with a following action y, then we also have hb(x, y).
请注意,在我的操作列表中,
- 按照程序顺序,1 位于 2 之前;
- 3 和 4 相同;
- 2 与 3 同步。
至于您的其他问题,
- ad 1:
t
不必是 volatile 的,因为它是在线程创建之前写入的,并且以后不会发生变化。启动线程会自行引发 happens-before; - 广告 3:
setPause
不必同步,因为它所做的只是设置 volatile 变量。
关于java - Java中的线程结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24823590/