怎么使用 ConcurrentHashMap 才能是线程安全的?

public class test {
    public static ConcurrentHashMap chm = new ConcurrentHashMap();
    public static void main(String[] args)
    {
        for(int i=1;i<100;i++)
        {
            th t = new th(i);
            t.start();
        }
 
    }
}
class th extends Thread
{
    private int number = 0;
    public th(int _number)
    {
        number = _number;
    }
     
    @Override
    public void run()
    {
         
        boolean bo = true;
        while(bo){
                int state = test.chm.get("test") == null ? 0 : (Integer)test.chm.get("test");
                if(state == 9 )
                {
                    System.out.println("线程:"+number+",停止!");
                    bo = false ;
                }else
                {
                    state = (int)(Math.random() * 100);
                    test.chm.put("test", state);
                    System.out.println("线程:"+number+",修改操作,状态="+state);
                }
        }
    }
}


今天做了下测试,100个并发,通过ConcurrentHashMap 来存储数据来保证线程安全,
正确测试结果就是当一个线程随机数为9的时候,所有线程停止工作,但多执行几次还会发现,并发访问时,一个线程改变state为9,后其他线程还有继续在工作的.
线程:1,修改操作,状态=1
线程:2,修改操作,状态=9
线程:4,修改操作,状态=81
线程:6,停止!
线程:3,停止!
线程:8,停止!
线程:10,停止!
线程:7,停止!

检查了下 是多个线程执行到else里面时,state已经被之前的线程改为9了 ,造成的,说白了就是修改state=9这个线程在put之前,其他多个线程已经从map里读取stage的数据了,所以当state改成9,这些线程还可以执行else里面代码,并且将state又改成其他数了.

我可以通过同步代码块解决这问题,但就没有使用ConcurrentHashMap 的必须要了hashmap也可以做到.不知道是否我是ConcurrentHashMap 有问题?


ConcurrentHashMap 只是保证本身map的线程安全,不保证你自己写的程序的同步.

你可以采用客户端加锁实现同步

synchronized(test.chm)

转载地址:http://www.oschina.net/question/236000_71020

猜你喜欢

转载自hck.iteye.com/blog/2201864