java程序的线程内语义



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

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?

JLS在17.4说:

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

我认为线程内语义意味着线程将像程序中的单个线程一样工作。也就是说,由th1分配的值仅对于th1是可观察的,并且对于th2是类似的。

我可能没有正确理解线程内语义概念?

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

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

而不是"线程内"操作。两个线程共享一个共同的内存位置(变量sync),从一个线程设置值是一种效果,另一个线程可以检测到。"线程内"语义的描述说明

每个线程在隔离状态下的操作都必须由该线程的语义控制,,但每次读取所看到的值由内存模型确定除外。

(强调矿,来源)

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

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

另一方面,您的程序没有正确同步,因为您有两个线程在向同一个静态变量(sync)写入,因此程序可以同时产生输出(6,2)和(2,2),并且仍然实现JMM。

最新更新