开发者社区> 问答> 正文

怎样提升这个多线程bug重现的几率?(java程序报错)

"

《java concurrency in practice》中有一段代码如下:

class HolderPlace{ public Holder holder; public void initHolder(){ holder = new Holder(42); } }

class Holder{ private int n;

public Holder(int n) {
    this.n = n;
}

public void assertSanity(){
    if(n!=n){
        throw new AssertionError("....Assertion error...");
    }
}

}

理论上呢,也能看懂为啥线程不安全,比如如果是下边的操作:
执行HolderPlacer.holder.assertSanity的(n!=n) 的第一个n时Holder还没给n赋值呢,但是等到第二个n执行完值给赋上了,就导致了(n!=n)==true

HolderPlace place = new HolderPlace();
           new Thread(()->place.initHolder()).start();
           new Thread(()->{
               try{
                   place.holder.assertSanity();
               }catch (NullPointerException e){

               }
           }).start();

但是我想让这个bug出现,应该怎么做才能提高bug出现的概率?
总不能光让我凭理论分析。

感谢回答者

@@@@@@@@@@@@@@@@@@编辑分割线 。。。刚才给添加到评论里了@@@@@@@@@@@@@@@@

怕大家走偏了,

我是想证明真的存在“虽然构造函数已经执行完成,引用也指向了这个对象,但是,这个对象的非final域可能还未真正的赋值”

再举个例子如下:

public class Tx {
    public int n;

    public Tx(int n) {
        this.n = n;
    }
}


public class Cons {

    public static final int INIT_NUM = 100;
    public static void main(String[] args) {
        for(int i=0;i<10000;i++){
            Map m = new HashMap<>();
            new Thread(()->{m.put("a",new Tx(INIT_NUM));}).start();
            new Thread(()->{
                try {
                    Assert.assertEquals(INIT_NUM,((Tx)m.get("a")).n);
                }catch (NullPointerException e){
                    //do nothing
                }
            }).start();
        }

    }
}

但是这段代码我仍然跑不出来异常。。。。(或者有没有人能提供能证明这个问题的例子,还要能跑出结果来。。。

" ![image.png](https://ucc.alicdn.com/pic/developer-ecology/f364db1831c24886ace1646a6ccd51f7.png)

展开
收起
因为相信,所以看见。 2020-05-25 15:58:29 821 0
1 条回答
写回答
取消 提交回答
问答排行榜
最热
最新

相关电子书

更多
如何通过 Serverless 提高 Java 微服务治理效 立即下载
Spring Cloud Alibaba - 重新定义 Java Cloud-Native 立即下载
多IO线程优化版 立即下载