首頁  >  文章  >  Java  >  java向多執行緒傳遞參數的三種方法詳細介紹

java向多執行緒傳遞參數的三種方法詳細介紹

高洛峰
高洛峰原創
2017-01-22 10:55:541755瀏覽

在傳統的同步開發模式下,當我們呼叫一個函數時,透過這個函數的參數將資料傳入,並透過這個函數的回傳值來傳回最終的計算結果。但在多執行緒的非同步開發模式下,資料的傳遞和回傳和同步開發模式有很大的差別。由於線程的運行和結束是不可預料的,因此,在傳遞和返回資料時就無法像函數一樣透過函數參數和return語句來傳回資料。本文就以上原因介紹了幾種用於向線程傳遞資料的方法,在下一篇文章中將介紹從線程中傳回資料的方法。 

欲先取之,必先予之。一般在使用執行緒時都需要有一些初始化數據,然後執行緒利用這些數據進行加工處理,並傳回結果。在這個過程中最先要做的就是向線程中傳遞資料。 

一、透過建構方法傳遞資料 
在建立執行緒時,必須建立一個Thread類別的或其子類別的實例。因此,我們不難想到在呼叫start方法之前透過執行緒類別的建構方法將資料傳入執行緒。並將傳入的資料使用類別變數保存起來,以便執行緒使用(其實就是在run方法中使用)。下面的程式碼示範如何透過建構方法來傳遞資料: 

package mythread; 
public class MyThread1 extends Thread 
{ 
private String name; 
public MyThread1(String name) 
{ 
this.name = name; 
} 
public void run() 
{ 
System.out.println("hello " + name); 
} 
public static void main(String[] args) 
{ 
Thread thread = new MyThread1("world"); 
thread.start(); 
} 
}

由於這個方法是在建立執行緒物件的同時傳遞資料的,因此,在執行緒運行之前這些資料就已經到位了,這樣就不會造成資料在執行緒運行後才傳入的現象。如果要傳遞更複雜的數據,可以使用集合、類別等資料結構。使用構造方法來傳遞資料雖然比較安全,但如果要傳遞的資料比較多時,就會造成很多不便。由於Java沒有預設參數,要實現類似預設參數的效果,就得使用重載,這樣不但使構造方法本身過於複雜,又會使構造方法在數量上大增。因此,要避免這種情況,就得透過類別方法或類別變數來傳遞資料。

二、透過變數和方法傳遞資料 
向物件中傳入資料一般有兩次機會,第一次機會是在建立物件時透過建構方法將資料傳入,另外一次機會就是在類別中定義一系列的public的方法或變數(也可稱之為欄位)。然後在建立完物件後,透過物件實例逐一賦值。下面的程式碼是MyThread1類別的改版,使用了一個setName方法來設定 name變數: 

package mythread; 
public class MyThread2 implements Runnable 
{ 
private String name; 
public void setName(String name) 
{ 
this.name = name; 
} 
public void run() 
{ 
System.out.println("hello " + name); 
} 
public static void main(String[] args) 
{ 
MyThread2 myThread = new MyThread2(); 
myThread.setName("world"); 
Thread thread = new Thread(myThread); 
thread.start(); 
} 
}

三、透過回呼函數傳遞資料 
上面討論的兩種向執行緒傳遞資料的方法是最常用的。但這兩種方法都是main方法中主動將資料傳入線程類別的。這對於線程來說,是被動接收這些數據的。然而,在有些應用中需要在線程運行的過程中動態地獲取數據,如在下面代碼的run方法中產生了3個隨機數,然後通過Work類的process方法求這三個隨機數的和,並透過Data類別的value將結果傳回。從這個例子可以看出,在回傳value之前,必須要得到三個隨機數。也就是說,這個 value是無法事先就傳入線程類別的。 

package mythread; 
class Data 
{ 
public int value = 0; 
} 
class Work 
{ 
public void process(Data data, Integer numbers) 
{ 
for (int n : numbers) 
{ 
data.value += n; 
} 
} 
} 
public class MyThread3 extends Thread 
{ 
private Work work; 
public MyThread3(Work work) 
{ 
this.work = work; 
} 
public void run() 
{ 
java.util.Random random = new java.util.Random(); 
Data data = new Data(); 
int n1 = random.nextInt(1000); 
int n2 = random.nextInt(2000); 
int n3 = random.nextInt(3000); 
work.process(data, n1, n2, n3); // 使用回调函数 
System.out.println(String.valueOf(n1) + "+" + String.valueOf(n2) + "+" 
+ String.valueOf(n3) + "=" + data.value); 
} 
public static void main(String[] args) 
{ 
Thread thread = new MyThread3(new Work()); 
thread.start(); 
} 
}

在上面程式碼中的process方法稱為回呼函數。從本質上來說,回調函數就是事件函數。在Windows API中常使用回呼函數和呼叫API的程式之間進行資料互動。因此,呼叫回呼函數的過程就是最原始的引發事件的過程。在這個例子中呼叫了process方法來獲得資料也就相當於在run方法中引發了一個事件。 

更多java傳遞參數給多執行緒的三種方法詳細介紹相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn