【java并发】线程范围内共享数据
假定现在有个公共的变量data,有不同的线程都可以去操作它,如果在不同的线程对data操作完成后再去取这个data,那末肯定会出现线程间的数据混乱问题,由于A线程在取data数据前可能B线程又对其进行了修改,下面写个程序来讲明1下该问题: public class ThreadScopeShareData {
private static int data = 0;//公共的数据
public static void main(String[] args) {
for(int i = 0; i < 2; i ++) { //开启两个线程
new Thread(new Runnable() {
@Override
public void run() {
int temp = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " has put a data: " + temp); //打印出来为了看效果
data = temp; //操作数据:赋新值
new TestA().getData();
new TestB().getData();
}
}).start();
}
}
static class TestA {
public void getData() {
System.out.println("A get data from " + Thread.currentThread().getName() + ": " + data);//取出公共数据data
}
}
static class TestB {
public void getData() {
System.out.println("B get data from " + Thread.currentThread().getName() + ": " + data);
}
}
} 来看1下打印出来的结果:
从结果中可以看出,两次对data赋的值确切不1样,但是两个线程最后打印出来的都是最后赋的那个值,说明Thread-0拿出的数据已不对了,这就是线程间同享数据带来的问题。 public class ThreadScopeShareData {
private static int data = 0;//公共的数据
//定义1个Map以键值对的方式存储每一个线程和它对应的数据,即Thread:data
private static Map<Thread,Integer> threadData = Collections.synchronizedMap(new HashMap<Thread,Integer>());
public static void main(String[] args) {
for(int i = 0; i < 2; i ++) {
new Thread(new Runnable() {
@Override
public void run() {
int temp = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " has put a data: " + temp); //打印出来为了看效果
threadData.put(Thread.currentThread(),temp); //向Map中存入本线程data数据的1个副本
data = temp; //操作数据:赋新值
new TestA().getData();
new TestB().getData();
}
}).start();
}
}
static class TestA {
public void getData() {
System.out.println("A get data from " + Thread.currentThread().getName() + ": "
+ threadData.get(Thread.currentThread())); //取出各线程保护的那个副本
}
}
static class TestB {
public void getData() {
System.out.println("B get data from " + Thread.currentThread().getName() + ": "
+ threadData.get(Thread.currentThread()));
}
}
} 上面程序中保护了1个Map,键值对分别是线程和它的数据,那末在操作data的时候,先把各自的数据保存到这个Map中,这样每一个线程保存的肯定不同,当再取的时候,根据当前线程对象作为key来取出对应的data副本,这样不同的线程之间就不会相互影响了。这个HashMap也需要包装1下,由于HashMap是非线程安全的,上面的程序中,不同的线程有对HashMap进行写操作,就有可能产生并提问题,所以也要包装1下。最后来看1下履行结果:
就是线程范围内同享数据,即同1个线程里面这个数据是同享的,线程间是不同享的。 —–乐于分享,共同进步! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |