-
package util;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class test {
public static Map<String, Integer> chm = new ConcurrentHashMap<String, Integer>();
public static void main(String[] args) {
test.chm.put("test", 1);
tht t1 = new tht();
t1.start();
for (int i = 1; i < 1000; 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 = 0;
state = (Integer) test.chm.get("test");
if (state == 9) {
System.out.println("线程:" + number + ",停止!");
bo = false;
} else {
System.out.println("线程:" + number + ",state=" + state + ",time:" + System.currentTimeMillis());
}
}
}
}
class tht extends Thread {
public tht() {
}
@Override
public void run() {
boolean bo = true;
while (bo) {
int state = 0;
state = (int) (Math.random() * 1000000);
test.chm.put("test", state);
if (state == 9) {
System.out.println("线程:-1,停止,time=" + System.currentTimeMillis()
+ ",--------------------------------------------");
bo = false;
}
}
}
}
运行多次运行后出现结果:
线程:237,state=178474,time:1348219230671
线程:-1,停止,time=1348219230671,--------------------------------------------
线程:236,state=178474,time:1348219230671
线程:337,state=178474,time:1348219230671
线程:876,state=178474,time:1348219230671
ConcurrentHashMap不是线程安全的么,那么多个线程同时读和改的时候,从运行结果看改的线程获取到锁以后,读的线程还是可以继续执行的.到底怎么使用ConcurrentHashMap才能保证数据一致?
问题补充:正常应该是,改state赋值为9后,所有读线程停止工作.但改的线程put时,读的线程并没有等待放锁后在读呢?
解答:
我不知道这位兄台有没有测试过,加不加synchronized效果是一样的;本身ConcurrentHashMap本身就是线程安全的,这个安全只存在于put和get操作,之所以出现楼主这种情况,就是你说的线程调度问题,楼主把这个//System.out.println("线程:"+number+",停止!"); 去掉注释后运行,是不是可以看到所有的线程最终停止了;前面多了些
线程:236,state=178474,time:1348219230671
线程:337,state=178474,time:1348219230671
线程:876,state=178474,time:1348219230671
这样的信息,为什么?
那是因为在chm被插入9之前,有些线程比如A线程运行到int state = (Integer)test.chm.get("test"); 此时得到state不是9,线程调度切换到插入9的线程B,此test.chm被插入9,B结束;切换为A继续执行,发什么什么,打印了这句:
线程:236,state=178474,time:1348219230671
因为这里的state是插入9之前的值;
什么时候结束,下一次循环重新得到的state就是9了。
所以说不论加不加synchronzied都会出现这种效果,线程调度的问题;
总结:
(1)ConcurrentMap是线程安全的,这种安全只存在于对他自己的操作,不能保证外部;
(2)线程调度可能引起开始错误的结果。
-
======================To be Continued======================
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)