首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >易失性jls示例

易失性jls示例
EN

Stack Overflow用户
提问于 2013-01-14 03:29:07
回答 1查看 199关注 0票数 1

如果下面的代码不会在Windows7 x86 JDK7(打开了-ea )上为每个JLS example for volatile抛出AssertionError

代码语言:javascript
复制
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();
    }
}
};
EN

回答 1

Stack Overflow用户

发布于 2013-01-14 03:46:54

您有多个线程在运行oneij是易失性的,因此更改是可见的,但是i++j++不是原子操作,并且很可能其中一个计数器在某个阶段不会正确递增:

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

  • 线程1: read I => 5
  • Thread2: read I => 5
  • Thread1: temp =i+1 => 6
  • Thread2: temp =i+1 => 6
  • 线程1: write I= temp => 6

线程2: write I= temp => 6

  • 线程1: read j and increment => j=6
  • 线程2: read j and increment => j= 7

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

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

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14307277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档