线程范围内的共享变量(一)
关于线程范围内的变量共享,这种应用场景,在实际开发中应用不是很多,但对理解和加深多线程编程却有很大的好处!这里在网上找了一些资料,收藏仅供以后学习:
创建两个个线程,他们都访问同一个变量,要求同一个线程设置的值只能被自身所获取!
package com.datashare;import java.util.Random;public class ThreadDataShare {public static int data = 0;public static void main(String[] args) throws Exception {for (int i = 0; i < 2; i++) {new Thread(new Runnable() {@Overridepublic void run() {data = new Random().nextInt();System.out.println(Thread.currentThread().getName()+ " has put data :" + data);new A().get();new B().get();}}).start();}}static class A {public void get() {System.out.println("A from " + Thread.currentThread().getName()+ " get data : " + data);}}static class B {public void get() {System.out.println("A from " + Thread.currentThread().getName()+ " get data : " + data);}}}
运行结果如下:
Thread-0 has put data :1118128123Thread-1 has put data :1118128167A from Thread-1 get data : 1118128167A from Thread-0 get data : 1118128167B from Thread-1 get data : 1118128167B from Thread-0 get data : 1118128167
从结果中可以看出Thread-0该线程设置的值并没有被与该线程相关的类读取到!这使什么原因呢,这是因为,线程Thread-0刚把data设置值之后,还没来得及输出该值就被下个线程给改变了!所以线程一读取不到它自己设置的值!有可能甚至会出现Thread-0 has put data 和 Thread-1 has put data输出值相等的情况。
那怎么解决这种情况呢,办法有很多种:
其一:
package com.datashare;import java.util.Random;public class ThreadDataShare {public static int data = 0;public static void main(String[] args) throws Exception {for (int i = 0; i < 2; i++) {[b]Thread.sleep(100);[/b]new Thread(new Runnable() {@Overridepublic void run() {data = new Random().nextInt();System.out.println(Thread.currentThread().getName()+ " has put data :" + data);new A().get();new B().get();}}).start();}}static class A {public void get() {System.out.println("A from " + Thread.currentThread().getName()+ " get data : " + data);}}static class B {public void get() {System.out.println("B from " + Thread.currentThread().getName()+ " get data : " + data);}}}
粗体代码就是延长下个线程的创建时间,但是这样并不能解决根本问题!
方法二:
package com.datashare;import java.util.HashMap;import java.util.Map;import java.util.Random;public class ThreadDataShare {public static int data = 0;private static Map<Thread, Integer> map = new HashMap<Thread, Integer>();public static void main(String[] args) throws Exception {for (int i = 0; i < 2; i++) {new Thread(new Runnable() {@Overridepublic void run() {[b]int data = new Random().nextInt();[/b]map.put(Thread.currentThread(), data);System.out.println(Thread.currentThread().getName()+ " has put data :" + data);new A().get();new B().get();}}).start();}}static class A {public void get() {System.out.println("A from " + Thread.currentThread().getName()+ " get data : " + map.get(Thread.currentThread()));}}static class B {public void get() {System.out.println("B from " + Thread.currentThread().getName()+ " get data : " + map.get(Thread.currentThread()));}}}
其上实例是线程范围内变量共享的真实写照,上代码逻辑并不能于理解,需要注意的是data不是定义成了类变量了嘛,干嘛还要在此用一个方法的成员变量来覆盖!首先还得回到第一个实例,因为如果定义成类变量会出现第一个线程刚设置值马上又被第二个线程覆盖这种情况,所以才在方法里定义成方法的局部变量,每条线程会为各自的run方法分配各自的存储空间用于存储各自方法内部的局部变量,当这个方法结束时,分配给这个方法的栈就会被释放,栈中变量也会消失!而且很大程度上节省了内存!