java程序的内部线程语义

时间:2014-09-13 15:19:51

标签: java multithreading

下面的代码是否违反了线程内语义?

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();
 }

DEMO

结果是:

written thread 1
written thread 2
2
2 //!!!! Is intra-thread semantic violates?

17.4中的JLS说:

  

[...]如前所述,所有线程都需要遵守正确的   Java程序的线程内语义。[...]

我认为线程内语义意味着线程可以像程序中的单个线程一样工作。也就是说,th1分配的值仅适用于th1,而th2类似。

我可能无法正确理解线程内语义概念吗?

2 个答案:

答案 0 :(得分:2)

问题是,你得到了自己和"线程间"行动在这里

  

线程间操作是由一个线程执行的操作,可以被另一个线程检测到或直接受其影响。

不是"内部线程"行动。两个线程共享一个公共内存位置(变量sync),并且从一个线程设置值是一种效果,可以被另一个检测到。 "内部线程"的解除语义说

  

隔离的每个线程的操作必须按照该线程的语义来控制,除了每次读取所看到的值由内存模型确定之外。

(强调我的,source

答案 1 :(得分:1)

线程内语义仅指线程之间不共享的变量。

因此输出与Java内存模型(JMM)一致。

另一方面,您的程序未正确同步,因为您有两个线程写入相同的静态变量(sync),因此程序可以同时生成输出(6,2)以及(2) ,2)并且仍然履行JMM。