1. 程式人生 > >多執行緒訪問共享物件和資料的方式

多執行緒訪問共享物件和資料的方式

如果每個執行緒執行的程式碼相同,可以使用同一個Runnable物件,這個Runnable物件中有那個共享資料,比如:在之前提到的賣票程式中,是兩個執行緒,同時減去100張票,也就是說這兩個執行緒的操作都是一樣的,所以我們可以使用同一個Runnable物件。

如果每個執行緒執行的程式碼不同,這時候需要不同的Runnable物件,有如下兩種方式來實現這些Runnable物件之間的資料共享:
1:將共享的資料封裝在另外一個物件中,然後將這個物件逐一傳遞給各個Runnable物件,每個執行緒對共享資料的操作方法也分配到那個物件身上去。

2:將這些Runnable物件作為某一個類中的內部類,共享資料作為這個外部類中的成員變數,每個執行緒對共享資料的操作方法也分配給外部類。

案例:設計四個執行緒,其中兩個執行緒每次對變數j增加1,另外兩個執行緒每次減少1。

/**
 * 資料類
 */
class MyData {

	private int j = 0;

	/* 變數j的自增 */
	public synchronized void increment() {
		j++;
		System.out.println(Thread.currentThread().getName() +"自增: "+ j);
	}

	/* 變數j的自減 */
	public synchronized void decrement() {
		j--;
		System.out.println(Thread.currentThread().getName() +"自減: "+ j);
	}
}

/**
 * 使變數自增的執行緒類
 */
class MyRunnable1 implements Runnable {

	/* 定義資料類 */
	private MyData data;

	/* 通過建構函式把物件傳過來 */
	public MyRunnable1(MyData data) {
		this.data = data;
	}

	public void run() {
		/* 呼叫資料類中的方法,使變數自增 */
		data.increment();
	}

}

/**
 * 使變數自減的執行緒類
 */
class MyRunnable2 implements Runnable {

	/* 定義資料類 */
	private MyData data;

	/* 通過建構函式把物件傳過來 */
	public MyRunnable2(MyData data) {
		this.data = data;
	}

	public void run() {
		/* 呼叫資料類中的方法,使變數自增 */
		data.decrement();
	}

}

/**
 * 測試類
 */
public class MultiThreadShareData {

	public static void main(String[] args) {

		/******************** 實現Runnable物件之間資料共享的第一種方式 ***************************/
		/* 建立資料類 */
		MyData data = new MyData();
		
		/*迴圈建立四個執行緒*/
		for (int i=0; i<2; i++){
			/* 建立執行緒使變數自增 */
			new Thread(new MyRunnable1(data)).start();
			/* 建立執行緒使變數自減 */
			new Thread(new MyRunnable2(data)).start();
		}
		

		/******************** 實現Runnable物件之間資料共享的第二種方式 **************************
		final MyData data2 = new MyData();
		
		new Thread(new Runnable() {

			@Override
			public void run() {
				data2.decrement();
			}
		}).start();
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				data2.increment();
			}
		}).start();*/

	}

}