并發(fā)
并發(fā)主要解決:“速度” 和“設(shè)計可管理性” 問題
java的線程機制是搶占式的,表示 調(diào)度機制會周期性的中斷線程嘹黔,將上下文切換到另一個線程峭状,從而為每個線程都提供時間片,使的每個線程都會分配到數(shù)量合理的時間去驅(qū)動它的任務(wù)泊窘。
Runnable接口描述任務(wù)熄驼,實際實現(xiàn)在run方法中。
Thread.yield()方法對線程調(diào)度器的調(diào)用的一種建議烘豹,表示通知cpu將一個線程轉(zhuǎn)到另一個線程瓜贾,但是不實際執(zhí)行情況不一定會轉(zhuǎn)到另一個線程上去。這是一種選擇性的携悯。
Thread類
使用方式:
Thread t = new Thread(new Runnable());
t.start();
每個Thread都會“注冊”自己祭芦,自己引用自己,在它任務(wù)退出run()并且死亡之前憔鬼,垃圾處理器無法回收它
Executor
用來管理Thread對象龟劲,允許管理異步任務(wù)的執(zhí)行,無需顯示的管理線程的生命周期
使用方式:
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Runnable());
線程池:
CachedThreadPool : 每創(chuàng)建一個任務(wù)轴或,創(chuàng)建一個線程昌跌,在程序執(zhí)行過程中通常會創(chuàng)建與所需數(shù)量相同的線程,然后在它回收舊線程時停止創(chuàng)建新線程
FixedThreadPool :使用有限的線程來執(zhí)行所提交的任務(wù)
SingleThreadExecutor :線程數(shù)量為1的FixedThreadPool照雁,如果向SingleThreadExecutor提交多個任務(wù)蚕愤,那么這些任務(wù)將會排隊執(zhí)行每個任務(wù)都會在下一個任務(wù)開始之前運行結(jié)束,所有的任務(wù)都將使用同一個線程饺蚊。
從任務(wù)中返回值(Callable接口)
Runnable接口沒有返回值萍诱,需要執(zhí)行的任務(wù)返回結(jié)果,使用Callable接口(具有泛型的類型參數(shù))污呼,它的類型參數(shù)表示的是從call()方法中返回的值裕坊,并切必須使用ExecutorService.submit()方法調(diào)用它。
使用方式:
//自定義callable接口
class IvyCallable implements Callable<String> {
public void IvyCallable(){}
public String call(){
return "返回期望返回的類型";
}
}
//demo
ExecutorService exec = Executors.newCachedThreadPool();
Feture<String> future = exec.submit(new IvyCallable());
submit()方法會產(chǎn)生Future對象曙求,它用Callable返回結(jié)果的特定類型進行了參數(shù)化碍庵。可以使用Future.isDone()查詢Future是否已經(jīng)完成悟狱,任務(wù)完成時静浴,調(diào)用Future.get()方法來獲取任務(wù)執(zhí)行的返回結(jié)果〖方ィ可以不用isDone()進行檢查就直接調(diào)用get()苹享,這種情況下,gei()將阻塞,直至結(jié)果準備就緒得问。
線程優(yōu)先級
線程的優(yōu)先級將線程的重要性傳遞給調(diào)度器囤攀。cpu處理處理線程集的順序是不確定的澄干,但是調(diào)度器將傾向于優(yōu)先級最高的線程優(yōu)先執(zhí)行蔚润。優(yōu)先級較低的線程執(zhí)行的頻率較低。
getPriority()來讀取現(xiàn)有線程的優(yōu)先級湾笛,setPriority()設(shè)置線程優(yōu)先級漓骚。在一個任務(wù)的內(nèi)部蝌衔,可以通過調(diào)用Thread.currentThread()來獲的對驅(qū)動該任務(wù)的Thread對象的引用。
優(yōu)先級 級別: MAX_PRIORITY蝌蹂、NORM_PRIORITY噩斟、MIN_PRIORITY
讓步
給調(diào)度器一個暗示,表示任務(wù)已經(jīng)執(zhí)行的差不多了孤个,可以讓別的線程使用cpu了剃允。但是不能保證一定會被采納 ,通過調(diào)用yield()方法實現(xiàn)齐鲤。
后臺線程
含義:指在程序運行的時候在后臺提供一種通用服務(wù)的線程斥废,并且這種線程并不屬于程序中不可或缺的部分。
只要有任務(wù)非后臺線程還在運行佳遂,程序就不會終止营袜。
設(shè)置后臺線程:
thread daemon = new thread(new runanble());
daemon.setdaemon(true); //設(shè)置后臺線程
daemon.start();
必須在線程啟動前設(shè)置
可以通過isDaemon()方法來確定線程是否是一個后臺線程,如果是一個后臺線程丑罪,那么它創(chuàng)建的線程都被自動設(shè)置成后臺線程。
后臺線程不會執(zhí)行finnally語句
加入一個線程
一個線程可以在其他線程之上調(diào)用join()方法凤壁,其效果是等待一段時間直到第二個線程結(jié)束才繼續(xù)執(zhí)行吩屹。