下面的代码是否违反了线程内语义?
static Integer sync;
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
@Override
public void run() {
sync = 6;
System.out.println("written thread 1");
try {
Thread.sleep(9999);
} catch (InterruptedException ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(sync);
}
};
Runnable t = new Runnable() {
@Override
public void run() {
sync = 2;
System.out.println("written thread 2");
try {
Thread.sleep(9999);
} catch (InterruptedException ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(sync);
}
};
Thread th1 = new Thread(r);
Thread th2 = new Thread(t);
th1.start();
th2.start();
}
结果是:
written thread 1
written thread 2
2
2 //!!!! Is intra-thread semantic violates?
17.4中的JLS说:
[...]如前所述,所有线程都需要遵守正确的 Java程序的线程内语义。[...]
我认为线程内语义意味着线程可以像程序中的单个线程一样工作。也就是说,th1
分配的值仅适用于th1
,而th2
类似。
我可能无法正确理解线程内语义概念吗?
答案 0 :(得分:2)
问题是,你得到了自己和"线程间"行动在这里
线程间操作是由一个线程执行的操作,可以被另一个线程检测到或直接受其影响。
不是"内部线程"行动。两个线程共享一个公共内存位置(变量sync
),并且从一个线程设置值是一种效果,可以被另一个检测到。 "内部线程"的解除语义说
隔离的每个线程的操作必须按照该线程的语义来控制,除了每次读取所看到的值由内存模型确定之外。
(强调我的,source)
答案 1 :(得分:1)
线程内语义仅指线程之间不共享的变量。
因此输出与Java内存模型(JMM)一致。
另一方面,您的程序未正确同步,因为您有两个线程写入相同的静态变量(sync
),因此程序可以同时生成输出(6,2)以及(2) ,2)并且仍然履行JMM。