java向多線程中傳遞參數(shù)的三種方法詳細(xì)介紹
更新時(shí)間:2012年11月16日 09:59:01 作者:
但在多線程的異步開發(fā)模式下,數(shù)據(jù)的傳遞和返回和同步開發(fā)模式有很大的區(qū)別。由于線程的運(yùn)行和結(jié)束是不可預(yù)料的,因此,在傳遞和返回?cái)?shù)據(jù)時(shí)就無(wú)法象函數(shù)一樣通過(guò)函數(shù)參數(shù)和return語(yǔ)句來(lái)返回?cái)?shù)據(jù)
在傳統(tǒng)的同步開發(fā)模式下,當(dāng)我們調(diào)用一個(gè)函數(shù)時(shí),通過(guò)這個(gè)函數(shù)的參數(shù)將數(shù)據(jù)傳入,并通過(guò)這個(gè)函數(shù)的返回值來(lái)返回最終的計(jì)算結(jié)果。但在多線程的異步開發(fā)模式下,數(shù)據(jù)的傳遞和返回和同步開發(fā)模式有很大的區(qū)別。由于線程的運(yùn)行和結(jié)束是不可預(yù)料的,因此,在傳遞和返回?cái)?shù)據(jù)時(shí)就無(wú)法象函數(shù)一樣通過(guò)函數(shù)參數(shù)和return語(yǔ)句來(lái)返回?cái)?shù)據(jù)。本文就以上原因介紹了幾種用于向線程傳遞數(shù)據(jù)的方法,在下一篇文章中將介紹從線程中返回?cái)?shù)據(jù)的方法。
欲先取之,必先予之。一般在使用線程時(shí)都需要有一些初始化數(shù)據(jù),然后線程利用這些數(shù)據(jù)進(jìn)行加工處理,并返回結(jié)果。在這個(gè)過(guò)程中最先要做的就是向線程中傳遞數(shù)據(jù)。
一、通過(guò)構(gòu)造方法傳遞數(shù)據(jù)
在創(chuàng)建線程時(shí),必須要建立一個(gè)Thread類的或其子類的實(shí)例。因此,我們不難想到在調(diào)用start方法之前通過(guò)線程類的構(gòu)造方法將數(shù)據(jù)傳入線程。并將傳入的數(shù)據(jù)使用類變量保存起來(lái),以便線程使用(其實(shí)就是在run方法中使用)。下面的代碼演示了如何通過(guò)構(gòu)造方法來(lái)傳遞數(shù)據(jù):
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();
}
}
由于這種方法是在創(chuàng)建線程對(duì)象的同時(shí)傳遞數(shù)據(jù)的,因此,在線程運(yùn)行之前這些數(shù)據(jù)就就已經(jīng)到位了,這樣就不會(huì)造成數(shù)據(jù)在線程運(yùn)行后才傳入的現(xiàn)象。如果要傳遞更復(fù)雜的數(shù)據(jù),可以使用集合、類等數(shù)據(jù)結(jié)構(gòu)。使用構(gòu)造方法來(lái)傳遞數(shù)據(jù)雖然比較安全,但如果要傳遞的數(shù)據(jù)比較多時(shí),就會(huì)造成很多不便。由于Java沒(méi)有默認(rèn)參數(shù),要想實(shí)現(xiàn)類似默認(rèn)參數(shù)的效果,就得使用重載,這樣不但使構(gòu)造方法本身過(guò)于復(fù)雜,又會(huì)使構(gòu)造方法在數(shù)量上大增。因此,要想避免這種情況,就得通過(guò)類方法或類變量來(lái)傳遞數(shù)據(jù)。
二、通過(guò)變量和方法傳遞數(shù)據(jù)
向?qū)ο笾袀魅霐?shù)據(jù)一般有兩次機(jī)會(huì),第一次機(jī)會(huì)是在建立對(duì)象時(shí)通過(guò)構(gòu)造方法將數(shù)據(jù)傳入,另外一次機(jī)會(huì)就是在類中定義一系列的public的方法或變量(也可稱之為字段)。然后在建立完對(duì)象后,通過(guò)對(duì)象實(shí)例逐個(gè)賦值。下面的代碼是對(duì)MyThread1類的改版,使用了一個(gè)setName方法來(lái)設(shè)置 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();
}
}
三、通過(guò)回調(diào)函數(shù)傳遞數(shù)據(jù)
上面討論的兩種向線程中傳遞數(shù)據(jù)的方法是最常用的。但這兩種方法都是main方法中主動(dòng)將數(shù)據(jù)傳入線程類的。這對(duì)于線程來(lái)說(shuō),是被動(dòng)接收這些數(shù)據(jù)的。然而,在有些應(yīng)用中需要在線程運(yùn)行的過(guò)程中動(dòng)態(tài)地獲取數(shù)據(jù),如在下面代碼的run方法中產(chǎn)生了3個(gè)隨機(jī)數(shù),然后通過(guò)Work類的process方法求這三個(gè)隨機(jī)數(shù)的和,并通過(guò)Data類的value將結(jié)果返回。從這個(gè)例子可以看出,在返回value之前,必須要得到三個(gè)隨機(jī)數(shù)。也就是說(shuō),這個(gè) value是無(wú)法事先就傳入線程類的。
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); // 使用回調(diào)函數(shù)
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方法被稱為回調(diào)函數(shù)。從本質(zhì)上說(shuō),回調(diào)函數(shù)就是事件函數(shù)。在Windows API中常使用回調(diào)函數(shù)和調(diào)用API的程序之間進(jìn)行數(shù)據(jù)交互。因此,調(diào)用回調(diào)函數(shù)的過(guò)程就是最原始的引發(fā)事件的過(guò)程。在這個(gè)例子中調(diào)用了process方法來(lái)獲得數(shù)據(jù)也就相當(dāng)于在run方法中引發(fā)了一個(gè)事件。
欲先取之,必先予之。一般在使用線程時(shí)都需要有一些初始化數(shù)據(jù),然后線程利用這些數(shù)據(jù)進(jìn)行加工處理,并返回結(jié)果。在這個(gè)過(guò)程中最先要做的就是向線程中傳遞數(shù)據(jù)。
一、通過(guò)構(gòu)造方法傳遞數(shù)據(jù)
在創(chuàng)建線程時(shí),必須要建立一個(gè)Thread類的或其子類的實(shí)例。因此,我們不難想到在調(diào)用start方法之前通過(guò)線程類的構(gòu)造方法將數(shù)據(jù)傳入線程。并將傳入的數(shù)據(jù)使用類變量保存起來(lái),以便線程使用(其實(shí)就是在run方法中使用)。下面的代碼演示了如何通過(guò)構(gòu)造方法來(lái)傳遞數(shù)據(jù):
復(fù)制代碼 代碼如下:
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();
}
}
由于這種方法是在創(chuàng)建線程對(duì)象的同時(shí)傳遞數(shù)據(jù)的,因此,在線程運(yùn)行之前這些數(shù)據(jù)就就已經(jīng)到位了,這樣就不會(huì)造成數(shù)據(jù)在線程運(yùn)行后才傳入的現(xiàn)象。如果要傳遞更復(fù)雜的數(shù)據(jù),可以使用集合、類等數(shù)據(jù)結(jié)構(gòu)。使用構(gòu)造方法來(lái)傳遞數(shù)據(jù)雖然比較安全,但如果要傳遞的數(shù)據(jù)比較多時(shí),就會(huì)造成很多不便。由于Java沒(méi)有默認(rèn)參數(shù),要想實(shí)現(xiàn)類似默認(rèn)參數(shù)的效果,就得使用重載,這樣不但使構(gòu)造方法本身過(guò)于復(fù)雜,又會(huì)使構(gòu)造方法在數(shù)量上大增。因此,要想避免這種情況,就得通過(guò)類方法或類變量來(lái)傳遞數(shù)據(jù)。
二、通過(guò)變量和方法傳遞數(shù)據(jù)
向?qū)ο笾袀魅霐?shù)據(jù)一般有兩次機(jī)會(huì),第一次機(jī)會(huì)是在建立對(duì)象時(shí)通過(guò)構(gòu)造方法將數(shù)據(jù)傳入,另外一次機(jī)會(huì)就是在類中定義一系列的public的方法或變量(也可稱之為字段)。然后在建立完對(duì)象后,通過(guò)對(duì)象實(shí)例逐個(gè)賦值。下面的代碼是對(duì)MyThread1類的改版,使用了一個(gè)setName方法來(lái)設(shè)置 name變量:
復(fù)制代碼 代碼如下:
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();
}
}
三、通過(guò)回調(diào)函數(shù)傳遞數(shù)據(jù)
上面討論的兩種向線程中傳遞數(shù)據(jù)的方法是最常用的。但這兩種方法都是main方法中主動(dòng)將數(shù)據(jù)傳入線程類的。這對(duì)于線程來(lái)說(shuō),是被動(dòng)接收這些數(shù)據(jù)的。然而,在有些應(yīng)用中需要在線程運(yùn)行的過(guò)程中動(dòng)態(tài)地獲取數(shù)據(jù),如在下面代碼的run方法中產(chǎn)生了3個(gè)隨機(jī)數(shù),然后通過(guò)Work類的process方法求這三個(gè)隨機(jī)數(shù)的和,并通過(guò)Data類的value將結(jié)果返回。從這個(gè)例子可以看出,在返回value之前,必須要得到三個(gè)隨機(jī)數(shù)。也就是說(shuō),這個(gè) value是無(wú)法事先就傳入線程類的。
復(fù)制代碼 代碼如下:
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); // 使用回調(diào)函數(shù)
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方法被稱為回調(diào)函數(shù)。從本質(zhì)上說(shuō),回調(diào)函數(shù)就是事件函數(shù)。在Windows API中常使用回調(diào)函數(shù)和調(diào)用API的程序之間進(jìn)行數(shù)據(jù)交互。因此,調(diào)用回調(diào)函數(shù)的過(guò)程就是最原始的引發(fā)事件的過(guò)程。在這個(gè)例子中調(diào)用了process方法來(lái)獲得數(shù)據(jù)也就相當(dāng)于在run方法中引發(fā)了一個(gè)事件。
相關(guān)文章
Java設(shè)計(jì)模式中組合模式應(yīng)用詳解
組合模式,又叫部分整體模式,它創(chuàng)建了對(duì)象組的數(shù)據(jù)結(jié)構(gòu)組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的訪問(wèn)具有一致性。本文將通過(guò)示例為大家詳細(xì)介紹一下組合模式,需要的可以參考一下2022-11-11mybatis?plus新增(insert)數(shù)據(jù)獲取主鍵id的問(wèn)題
這篇文章主要介紹了mybatis?plus新增(insert)數(shù)據(jù)獲取主鍵id的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03SpringBoot詳細(xì)講解如何創(chuàng)建及刷新Spring容器bean
前面看spring源碼時(shí)可以發(fā)現(xiàn)refresh()方法十分重要。在這個(gè)方法中會(huì)加載beanDefinition,同時(shí)創(chuàng)建bean對(duì)象。那么在springboot中有沒(méi)有使用這個(gè)refresh()方法呢2022-06-06Java深入學(xué)習(xí)圖形用戶界面GUI之創(chuàng)建窗體
圖形編程中,窗口是一個(gè)重要的概念,窗口其實(shí)是一個(gè)矩形框,應(yīng)用程序可以使用其從而達(dá)到輸出結(jié)果和接受用戶輸入的效果,學(xué)習(xí)了GUI就讓我們用它來(lái)創(chuàng)建一個(gè)窗體2022-05-05深入理解Java設(shè)計(jì)模式之訪問(wèn)者模式
這篇文章主要介紹了JAVA設(shè)計(jì)模式之訪問(wèn)者模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解2021-11-11Maven?dependency?plugin使用心得總結(jié)
這篇文章主要給大家介紹了關(guān)于Maven?dependency?plugin使用心得的相關(guān)資料,Maven是一個(gè)常用的Java build Manager,使用Maven可以很好的對(duì)Java Project的dependency進(jìn)行管理,需要的朋友可以參考下2023-10-10Java中高效的判斷數(shù)組中某個(gè)元素是否存在詳解
相信大家在操作Java的時(shí)候,經(jīng)常會(huì)要檢查一個(gè)數(shù)組(無(wú)序)是否包含一個(gè)特定的值?這是一個(gè)在Java中經(jīng)常用到的并且非常有用的操作。同時(shí),這個(gè)問(wèn)題在Stack Overflow中也是一個(gè)非常熱門的問(wèn)題。本文將分析幾種常見用法及其時(shí)間成本,有需要的朋友們可以參考借鑒。2016-11-11Java中基于DeferredResult的異步服務(wù)詳解
這篇文章主要介紹了Java中基于DeferredResult的異步服務(wù)詳解,DeferredResult字面意思是"延遲結(jié)果",它允許Spring MVC收到請(qǐng)求后,立即釋放(歸還)容器線程,以便容器可以接收更多的外部請(qǐng)求,提升吞吐量,需要的朋友可以參考下2023-12-12