一:第一種情況
如果每個線程執行的代碼相同,可以使用同一個Runnable對象,這個Runnable對象中有那個共享的數據,列入賣票系統可以這麼實現。
二:第二種情況
如果每個線程執行的代碼不同,這個時候需要不同的Runnable對象,有如下兩種方式來實現這些Runable對象之間的的數據共享
·將共享數據封裝在另外一個對象中,然後將這個對象逐一傳給各個Runnable對象,每個線程對共享數據的操作方法也分配到那個對象上去完成,這樣容易實現針對該數據進行各個操作的互斥和通信
eg:
class MyRunnable1 implements Runnable{
private ShareData1 data;
public MyRunnable1(ShareData1 data){
this.data = data;
}
public void run() {
data.decrement();
}
}
class MyRunnable2 implements Runnable{
private ShareData1 data;
public MyRunnable2(ShareData1 data){
this.data = data;
}
public void run() {
data.increment();
}
}
class ShareData1{
private int j ;
public synchronized void increment(){
j++;
}
public synchronized void decrement(){
j--;
}
}
記住在調用的時候ShareData1,一定是同一個對象才行 調用方式如下:
ShareData1 data1 = new ShareData1();
new Thread(new MyRunnable1(data1)).start();
new Thread(new MyRunnable2(data1)).start();
·將這些Runnable作爲某一個類中的內部類,共享數據作爲這個外部類中的成原變量,每個線程對共享數據的操作也放到外部類中,以便實現對共享數據進行各個操作的互斥和通信,作爲內部類中各個Runnable對象調用外部內的這些方法
package com.qunar.thread;
public class multiThreadShareData {
private static ShareData1 data1 = new ShareData1();
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
data1.decrement();
}
}).start();
new Thread(new Runnable() {
public void run() {
data1.increment();
}
}).start();
}
}
class ShareData1{
private int j ;
public synchronized void increment(){
j++;
}
public synchronized void decrement(){
j--;
}
}
·上面兩種方式的組合:將共享數據封裝到另外一個對象中,每個線程對共享數據的操作也分配到那個對象上去完成,對象作爲這個類中的餓成員變量或者方法中的局部變量,每個線程的Runnable對象作爲外部類中的成員內部類或局部內部類
·總之,要同步互斥的幾段代碼最好是分別放在幾個獨立的方法中,這些方法再放到同一個類中,這樣比較容易實現他們之間的同步互斥和通信