多執行緒的建立和使用

2021-09-01 19:31:23 字數 3281 閱讀 2651

最近做郵件傳送功能時,客戶端操作程式等待時長,有時候會很長甚至會死執行緒,這個很不利於使用者的體驗,為了解決這個問題,我想到了使用多執行緒,讓系統在後台傳送郵件,使用者操作介面不受影響,從而保證使用者體驗軟體的流暢度。事實上完成後的效果還不錯,系統介面瞬間響應,郵件後台傳送,其快慢程度取決於郵件伺服器響應速率和網路!

下面說說我研究多執行緒的方法和心得。研究時我為了便捷,只做了檔案複製的demo,然後再將功能**移植到開發系統的郵件傳送功能中,這樣做是為了保證系統的安全性。

首先要知道使用多執行緒有兩種方法,一是繼承thread類,一種是實現runnable介面。由於繼承的侷限性,只能單繼承,所以一般情況下會先考慮實現runnable介面這種。

我們要開啟乙個執行緒,那麼必須先給他乙個入口即run()方法,run()方法裡可以寫業務處理方法,這樣乙個執行緒就能流通並處理業務了。具體**如下:

/*** 所有執行緒任務介面

* 其他執行緒任務必須繼承該類

** @author hadestage

*/public abstract class task implements runnable catch (exception e)

}/**

* 所有任務的核心業務邏輯執行,哪個業務需要開啟多執行緒就繼承該類,然後重寫該方法的業務功能

** @throws exception

*/public abstract task taskcore() throws exception;

/*** 是否需要立即執行

*/protected abstract boolean needexecuteimmediate();

}這個執行緒任務類是我們業務功能啟用多執行緒時可繼承的介面,繼承時只需重寫業務方法

taskcore()即可。

作為示例demo,我建立了乙個檔案複製的執行緒任務,具體**如下:

/*** 建立檔案執行緒任務

* * @author hadestage

*/public class filecreatortask extends task

/*** 執行建立任務動作

*/@override

public task taskcore() catch (ioexception e)

return null;

}/**

* 是否需要立即執行

** @return false

*/@override

protected boolean needexecuteimmediate()

}其中fileutil.copyfile(new file(sourcefilename), new file(targefilename));

就是我們的關鍵業務**,複製檔案。

有時候,我們複製檔案、上傳檔案、傳送郵件等不僅僅只有乙個任務,很有可能多個複製、上傳、傳送任務同時進行,這時我們開啟乙個執行緒好像有些不夠用了,總不能乙個乙個的執行緒新建吧。那麼我們就需要同時開啟多個執行緒了,這就涉及到執行緒池的概念了,就像資料庫連線池那樣,建乙個執行緒池,裡面設定執行緒數,這樣就能解決多執行緒任務了。

/*** 執行緒池

* 建立執行緒池,銷毀執行緒池,新增新任務

** @author hadestage

*/public final class threadpool

建立單例執行緒池,從而保證執行緒池只有乙個且外部無法建立新的執行緒池,設定池中預設執行緒數,但支援手動設定執行緒數,poolworker是當前類的內部類,它充當執行緒池裡的執行緒,下文會有介紹。

接下來就是在threadpool這個執行緒池類中新增方法,使它能在建立執行緒池時設定執行緒數。

// 預設執行緒5個

private threadpool()

}private threadpool(int pool_worker_num)

}// 建立預設執行緒數

public static synchronized threadpool getinstance()

// 建立規定的執行緒個數

public static synchronized threadpool getinstance(int threadnumber)

建立完執行緒池,開啟了需要的執行緒,就得提供能往執行緒池裡增加任務並執行任務的方法。

/*** 增加新的任務

* 每增加乙個新任務,都要喚醒任務佇列

* @param newtask

*/public void addtask(task newtask)

}/**

* 批量增加新任務

* @param taskes

*/public void batchaddtask(listtaskes)

taskqueue.add(taskes.get(i));

}/* 喚醒佇列, 開始執行 */

taskqueue.notifyall();

}for (int i = 0; i < taskes.size(); i++) }}

任務執行完成後,我們還需要做一項工作,總不能讓執行緒池裡的執行緒一直佔著坑不放吧,你用完了,別人還等著用呢,所以我們還得銷毀執行緒池,等要用了再呼叫就行了。

/*** 銷毀執行緒池

*/public synchronized void destroy()

taskqueue.clear();

}執行緒池threadpool類中的內部類,該類的作用是具體化執行緒池,乙個任務是否執行,何時執行,怎麼執行都是由這裡面進行統一調配的。

class poolworker extends thread

public void setisrunning(boolean isrunning)

public void stopworker()

public boolean iswaiting()

/*** 迴圈執行任務

* 這也許是執行緒池的關鍵所在

*/public void run() catch (interruptedexception ie)

}/* 取出任務執行 */

r = (task) taskqueue.remove(0);

}if (r != null) else

} catch (exception e)

iswaiting = true;

r = null;}}

}}以上就是對執行緒池的建立和應用。現在有了業務功能,有了任務,也有了建立執行緒池和執行緒的方法,接下來就可以測試下了,可以新建乙個帶有main()函式的類,在main()方法裡建立執行緒池,然後新增任務即可了。具體**如下:

public static void main(string args)

多執行緒程式設計 執行緒的建立和終止

1 引言 linux 系統下的多執行緒遵循posix 執行緒介面,稱為pthread 編寫linux 下的多執行緒程式,需要使用標頭檔案pthread.h 連線時需要使用庫libpthread.a 順便說一下,linux 下pthread 的實現是通過系統呼叫clone 來實現的。clone 是li...

多執行緒程式設計 執行緒的建立和終止

1 引言 linux系統下的多執行緒遵循posix執行緒介面,稱為pthread。編寫linux下的多執行緒程式,需要使用標頭檔案pthread.h,連線時需要使用庫libpthread.a。順便說一下,linux下pthread的實現是通過系統呼叫clone 來實現的。clone 是linux所特...

多執行緒程式設計 執行緒的建立和終止

1 引言 linux系統下的多執行緒遵循posix執行緒介面,稱為pthread。編寫linux下的多執行緒程式,需要使用標頭檔案pthread.h,連線時需要使用庫libpthread.a。順便說一下,linux下pthread的實現是通過系統呼叫clone 來實現的。clone 是linux所特...