gpt4 book ai didi

java - volatile jls 示例

转载 作者:行者123 更新时间:2023-11-29 03:38:25 24 4
gpt4 key购买 nike

根据 JLS example for volatile,以下代码是否应该在 Windows 7 x86 jdk 7(打开 -ea)上抛出 AssertionError ?

public class TestVolatile {
static volatile int i = 0;
static volatile int j = 0;

static void one() {
i++;
j++;
assert (i>=j);
//:"one: i=" + i + " j=" + j;
}
static void two() {
//System.out.println("i=" + i + " j=" + j);
assert (i<=j);
/*
System.out.print("<i=" + i);
for (int k = 0; k < 1000000; k++);
System.out.println(", j=" + j+">");
*/
}
public static final int NUM_WORKERS = 4;

public static void main (String [] args) {
final Worker [] workers = new Worker[NUM_WORKERS];
final Thread [] workerThreads = new Thread[NUM_WORKERS];

for (int i = 0; i < NUM_WORKERS; i++) {
Worker w = new Worker(i);
workers[i] = w;
workerThreads[i] = new Thread(w,"workerThread_"+i);
}

for (int i = 0; i < NUM_WORKERS; i++) {
workerThreads[i].start();
}

}


}

final class Worker implements Runnable {
final int id;
volatile boolean notDone = true;


public Worker(int tid){
id = tid;
}

@Override
public void run() {
//System.out.println("worker start:" + id);
try {
while (notDone) {
if (id < TestVolatile.NUM_WORKERS - 1) {
TestVolatile.one();
} else {
TestVolatile.two();
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
};

最佳答案

您有超过 1 个线程在运行 oneij 是可变的,所以变化是可见的,但是 i++j++ 不是原子操作,并且很可能其中一个计数器在某个阶段不会正确递增:

例如,假设 i 为 5,以显示可以抛出 AssertionError 的有效线程交错:

  • 线程 1:读取 i => 5
  • 线程 2:读取 i => 5
  • 线程 1:temp = i + 1 => 6
  • 线程 2:temp = i + 1 => 6
  • 线程 1:写入 i = temp => 6
  • 线程 2:写入 i = temp => 6
  • 线程 1:读取 j 并递增 => j = 6
  • 线程 2:读取 j 并递增 => j = 7

并且 i 和 j 不同步,您在 one 中的断言将失败。

但是,尽管存在数据竞争,程序的运行仍有可能不会抛出断言错误:JLS 不保证您的程序会正常运行,但它并没有说它不会'要么。

编辑:编写 JLS 的“线程和锁”部分的人之一实际上有一个 post on his blog关于一个非常相似的问题。评论甚至提到了您在问题中提到的 JLS 部分:JLS 示例中只有一个编写线程。

关于java - volatile jls 示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14307277/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com