實現線程範圍內的數據共享就是各自的線程管理各自線程上的數據,不被另外線程干擾。大個比方: 當第一個線程運行的時候往一集合裏放一數據(比如是2),當第二個線程運行過來的時候往相同的集合裏相同的位置上放了數據3,這時通常情況下是3將2覆蓋掉了,然而在這裏不是這樣的,他們是兩個不同的線程,不能有衝突,這要怎麼解決呢? 有兩種辦法,使的當第一個線程再次運行都這裏時,取出數據是2,當第二個線程也再次運行到這裏時候取出數據是3, 這樣取出的數據是剛開始放入的數據,沒有產生衝突。
第一種方法:
使用Map
package cn.itcast.thread; import java.util.HashMap; import java.util.Map; import java.util.Random; public class ThreadLocalShare { /** * @param args */ //private static int data; private static Map shareData = new HashMap(); public static void main(String[] args) { for (int i=0; i<2; i++) { new Thread(){ public void run() { int data = new Random().nextInt(); shareData.put(Thread.currentThread(), data); System.out.println(Thread.currentThread().getName() + " put data is " + data); System.out.println(Thread.currentThread().getName() + " A get data is " + new A().get()); System.out.println(Thread.currentThread().getName() + " B get data is " + new B().get()); } }.start(); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } static class A { public int get() { synchronized (ThreadLocalShare.class) { try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return (Integer)shareData.get(Thread.currentThread()); } } } static class B { public int get() { synchronized (ThreadLocalShare.class) { try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return (Integer)shareData.get(Thread.currentThread()); } } } }
第二種方法:
使用ThreadLocal類
package cn.itcast.thread; import java.util.Random; import cn.itcast.thread.ThreadLocalShare.A; import cn.itcast.thread.ThreadLocalShare.B; public class ThreadLocalShare2 { private static ThreadLocal shareData = new ThreadLocal(); public static void main(String[] args) { for (int i=0; i<2; i++) { new Thread(){ public void run() { int data = new Random().nextInt(); //shareData.set(data); MyData.getInstance().setData(data); System.out.println(Thread.currentThread().getName() + " put data is " + data); System.out.println(Thread.currentThread().getName() + " A get data is " + new A().get()); System.out.println(Thread.currentThread().getName() + " B get data is " + new B().get()); System.out.println(Thread.currentThread().getName() + " C get data is " + new C().get()); } }.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } static class A { public int get() { synchronized (ThreadLocalShare.class) { try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return MyData.getInstance().getData(); } } } static class B { public int get() { synchronized (ThreadLocalShare.class) { try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return MyData.getInstance().getData(); } } } static class C { public int get() { synchronized (ThreadLocalShare.class) { try { Thread.sleep(new Random().nextInt(100)); } catch (InterruptedException e) { e.printStackTrace(); } return MyData.getInstance().getData(); } } } } class MyData { private static ThreadLocal instanceHolder = new ThreadLocal(); private int data; private static MyData instance = new MyData(); private MyData() {} public static MyData getInstance() { MyData instance = (MyData) instanceHolder.get(); if (instance == null) { instance = new MyData(); instanceHolder.set(instance); } return instance; } public void setData(int data) { this.data = data; } public int getData() { return data; } }