1. 程式人生 > >執行緒範圍內共享資料(一)

執行緒範圍內共享資料(一)

Java開發過程中,若單個執行緒需要在多個物件與模組中訪問同一個變數,則通過靜態變數就可以實現,那麼問題來了,當存在多個執行緒,多個物件與模組去訪問同一變數時,就不行了。例如

public class ThreadShare {
		private static int data = 0;		
		public static void main(String[] args) {
			for(int i=0;i<3;i++){
				new Thread(new Runnable(){
					@Override
					public 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);
			}		
		}
}



這樣輸出的結果如下:
Thread-0 has put data :961464780
Thread-1 has put data :180723255
A from Thread-0 get data :961464780
A from Thread-1 get data :180723255
B from Thread-0 get data :180723255
B from Thread-1 get data :180723255


可見存在多個執行緒時,A、B不同的模組中訪問的同一變數得到的不是同一個值。那麼如何才能保證多執行緒時,不同物件模組中訪問的同一變數是同一的值呢??

兩種方式:

(一)通過HashMap來存取。

(二)呼叫ThreadLocal類來實現

本篇講述方式一,程式碼實現如下:

public class ThreadShare {
	
		private static int data = 0;
		private static Map<Thread, Integer> threadData=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 data = new Random().nextInt();
						System.out.println(Thread.currentThread().getName() 
								+ " has put data :" + data);
						threadData.put(Thread.currentThread(), data);
						new A().get();
						new B().get();
					}
				}).start();
			}
		}
		
		static class A{
			public void get(){
				int data=threadData.get(Thread.currentThread());
				System.out.println("A from " + Thread.currentThread().getName() 
						+ " get data :" + data);
			}
		}
		
		static class B{
			public void get(){	
				int data=threadData.get(Thread.currentThread());
				System.out.println("B from " + Thread.currentThread().getName() 
						+ " get data :" + data);
			}		
		}
}

輸出結果為
Thread-1 has put data :-936867372
Thread-0 has put data :1218414176
A from Thread-0 get data :1218414176
A from Thread-1 get data :-936867372
B from Thread-0 get data :1218414176
B from Thread-1 get data :-936867372

可見,執行緒Thread-0中,A、B模組中訪問的data變數都是1218414176;Thread-1中,A、B模組中訪問的data變數都是-936867372。

至此,已經實現了執行緒範圍內資料的共享。下一篇通過呼叫ThreadLocal類來實現。