管理线程共享数据
方法1:
将共享数据封装在一个类的对象中,然后将这个对象传递给各个 Runnable对象
每个线程对共享数据的操作方法也分配到相应的对象身上去完成
示例代码:
1 public class Test { 2 private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>(); 3 public static void main(String[] args) { 4 for(int i=0;i<2;i++){ 5 new Thread( 6 new Runnable(){ 7 @Override 8 public void run(){ 9 int data = new Random().nextInt(); 10 System.out.println(Thread.currentThread().getName() 11 + " has put data :" + data); 12 MyThreadScopeData myData = new MyThreadScopeData();//在静态方法中创建一个封装共享数据的对象(内部类的实例) 13 myData.setName("name " + data); 14 myData.setAge(data); 15 myThreadScopeData.set(myData); 16 new A().get(); 17 new B().get(); 18 } 19 }).start(); 20 } 21 } 22 23 static class A{ 24 public void get(){ 25 MyThreadScopeData myData = myThreadScopeData.get(); 26 System.out.println("A from " + Thread.currentThread().getName() 27 + " getMyData :" + myData.getName() + "," + 28 myData.getAge()); 29 } 30 } 31 static class B{ 32 public void get(){ 33 MyThreadScopeData myData = myThreadScopeData.get(); 34 System.out.println("B from " + Thread.currentThread().getName() 35 + " getMyData :" + myData.getName() + "," + 36 myData.getAge()); 37 } 38 } 39 //封装共享数据的对象 40 static class MyThreadScopeData{ 41 private MyThreadScopeData(){} 42 private String name; 43 private int age; 44 public String getName() { 45 return name; 46 } 47 public void setName(String name) { 48 this.name = name; 49 } 50 public int getAge() { 51 return age; 52 } 53 public void setAge(int age) { 54 this.age = age; 55 } 56 } 57 }
运行结果如下:
Thread-0 has put data :1065945080 Thread-1 has put data :1729981827 A from Thread-1 getMyData :name 1729981827,1729981827 A from Thread-0 getMyData :name 1065945080,1065945080 B from Thread-0 getMyData :name 1065945080,1065945080 B from Thread-1 getMyData :name 1729981827,1729981827
从运行结果可以看出,A方法和B方法在同一线程中取到的是同一份数据,实现了线程的数据共享
方法2:
将 Runnable对象作为某一个类中的内部类
共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作方法也分配给外部类
作为内部类的各个 Runnable对象调用外部类的操作方法
示例代码:
1 public class Test { 2 private static Map<Thread, Integer> threadData = new HashMap<Thread, Integer>(); 3 public static void main(String[] args) { 4 for(int i=0;i<2;i++){ 5 new Thread( 6 new Runnable(){ 7 @Override 8 public void run(){ 9 int data = new Random().nextInt();//共享数据 10 System.out.println(Thread.currentThread().getName() 11 + " has put data :" + data); 12 threadData.put(Thread.currentThread(),data); 13 new A().get(); 14 new B().get(); 15 } 16 }).start(); 17 } 18 } 19 //操作方法A 20 static class A{ 21 public void get(){ 22 int data = threadData.get(Thread.currentThread()); 23 System.out.println("A from " + Thread.currentThread().getName() 24 + " get data :" + data); 25 } 26 } 27 //操作方法B 28 static class B{ 29 public void get(){ 30 int data = threadData.get(Thread.currentThread()); 31 System.out.println("B from " + Thread.currentThread().getName() 32 + " get data :" + data); 33 } 34 } 35 }
运行结果如下:
Thread-0 has put data :733399446 Thread-1 has put data :605369538 A from Thread-1 get data :605369538 A from Thread-0 get data :733399446 B from Thread-0 get data :733399446 B from Thread-1 get data :605369538
从运行结果也可以看出,A方法和B方法在同一线程中取到的是同一份数据
方法3:
如有需要,也可以将方法1和方法2组合起来使用,这里就不介绍了,还没试~~~