国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

多線程小記

suxier / 2081人閱讀

摘要:死亡狀態(tài)有兩個(gè)原因會(huì)導(dǎo)致線程死亡方法正常退出而自然死亡。一個(gè)未捕獲的異常終止了方法而使線程猝死。注意,放入的線程不必?fù)?dān)心其結(jié)束,超過不活動(dòng),其會(huì)自動(dòng)被終止。線程間相互干擾描述了當(dāng)多個(gè)線程訪問共享數(shù)據(jù)時(shí)可能出現(xiàn)的錯(cuò)誤。

線程 進(jìn)程與線程的區(qū)別

線程是指進(jìn)程內(nèi)的一個(gè)執(zhí)行單元,也是進(jìn)程內(nèi)的可調(diào)度實(shí)體。
一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程。

線程的五大狀態(tài)

新建狀態(tài)(New):例如new Thread(r)。

就緒狀態(tài)(Runnable): 當(dāng)start()方法返回后,線程就處于就緒狀態(tài)。

運(yùn)行狀態(tài)(Running) :當(dāng)線程獲得CPU時(shí)間后,它才進(jìn)入運(yùn)行狀態(tài),真正開始執(zhí)行run()方法。

阻塞狀態(tài):(Blocked)
線程運(yùn)行過程中,可能由于各種原因進(jìn)入阻塞狀態(tài):

線程通過調(diào)用sleep方法進(jìn)入睡眠狀態(tài)。

線程調(diào)用一個(gè)在I/O上被阻塞的操作,即該操作在輸入輸出操作完成之前不會(huì)返回到它的調(diào)用者。

線程試圖得到一個(gè)鎖,而該鎖正被其他線程持有。

線程在等待某個(gè)觸發(fā)條件。

死亡狀態(tài)(Dead)
有兩個(gè)原因會(huì)導(dǎo)致線程死亡:

run方法正常退出而自然死亡。

一個(gè)未捕獲的異常終止了run方法而使線程猝死。

為了確定線程在當(dāng)前是否存活著(就是要么是可運(yùn)行的,要么是被阻塞了),需要使用isAlive方法。如果是可運(yùn)行或被阻塞,這個(gè)方法返回true; 如果線程仍舊是new狀態(tài)且不是可運(yùn)行的, 或者線程死亡了,則返回false。

如何創(chuàng)建一個(gè)線程

從Java.lang.Thread類派生一個(gè)新的線程類,重寫它的run()方法

實(shí)現(xiàn)Runnalbe接口,重寫Runnalbe接口中的run()方法

實(shí)現(xiàn)Callable 接口,重寫Callable接口中的call()方法

Runnable和Callable的區(qū)別

Callable規(guī)定的方法是call(),Runnable規(guī)定的方法是run()。

Callable的任務(wù)執(zhí)行后可返回值,而Runnable的任務(wù)是不能返回值的。

call方法可以拋出異常,run方法不可以。

運(yùn)行Callable任務(wù)可以拿到一個(gè)Future對(duì)象,F(xiàn)uture 表示異步計(jì)算的結(jié)果。它提供了檢查計(jì)算是否完成的方法,以等待計(jì)算的完成,并獲取計(jì)算的結(jié)果。

如何安全退出一個(gè)已啟動(dòng)的線程

使用退出標(biāo)志:
當(dāng)run方法執(zhí)行完后,線程就會(huì)退出。但有時(shí)run方法是永遠(yuǎn)不會(huì)結(jié)束的,如在服務(wù)端程序中使用線程進(jìn)行監(jiān)聽客戶端請(qǐng)求,或是其他的需要循環(huán)處理的任務(wù)。在這種情況下,一般是將這些任務(wù)放在一個(gè)循環(huán)中,如while循環(huán)。如果想使while循環(huán)在某一特定條件下退出,最直接的方法就是設(shè)一個(gè)boolean類型的標(biāo)志,并通過設(shè)置這個(gè)標(biāo)志為true或false來控制while循環(huán)是否退出。

Sleep和Wait區(qū)別

對(duì)于sleep()方法,我們首先要知道該方法是屬于Thread類中的。而wait()方法,則是屬于Object類中的。

sleep()方法導(dǎo)致了程序暫停執(zhí)行指定的時(shí)間,讓出cpu該其他線程,但是他的監(jiān)控狀態(tài)依然保持者,當(dāng)指定的時(shí)間到了又會(huì)自動(dòng)恢復(fù)運(yùn)行狀態(tài)。

在調(diào)用sleep()方法的過程中,線程不會(huì)釋放對(duì)象鎖。而當(dāng)調(diào)用wait()方法的時(shí)候,線程會(huì)放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象調(diào)用notify()方法后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備。

線程池

由于線程的生命周期中包括創(chuàng)建、就緒、運(yùn)行、阻塞、銷毀階段,當(dāng)我們待處理的任務(wù)數(shù)目較小時(shí),我們可以自己創(chuàng)建幾個(gè)線程來處理相應(yīng)的任務(wù),但當(dāng)有大量的任務(wù)時(shí),由于創(chuàng)建、銷毀線程需要很大的開銷,運(yùn)用線程池這些問題就大大的緩解了。
相關(guān)參數(shù):

corePoolSize 核心池的大小

maximumPoolSize 線程池最大線程數(shù)

keepAliveTime 表示線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會(huì)終止

unit 參數(shù)keepAliveTime的時(shí)間單位

workQueue 一個(gè)阻塞隊(duì)列,用來存儲(chǔ)等待執(zhí)行的任務(wù)

threadFactory 線程工廠,主要用來創(chuàng)建線程

handler 表示當(dāng)拒絕處理任務(wù)時(shí)的策略

ThreadPoolExecutor mExecutor = new ThreadPoolExecutor(corePoolSize,// 核心池的大小
        maximumPoolSize, //線程池最大線程數(shù)  
        keepAliveTime, // 閑置線程存活時(shí)間  
        TimeUnit.MILLISECONDS,// 時(shí)間單位  
        new LinkedBlockingDeque(),//一個(gè)阻塞隊(duì)列,用來存儲(chǔ)等待執(zhí)行的任務(wù)  
        Executors.defaultThreadFactory(),//線程工廠,主要用來創(chuàng)建線程  
        new AbortPolicy()// 隊(duì)列已滿,而且當(dāng)前線程數(shù)已經(jīng)超過最大線程數(shù)時(shí)的異常處理策略  (表示當(dāng)拒絕處理任務(wù)時(shí)的策略)
);

當(dāng)提交的任務(wù)數(shù)達(dá)到coolPoolSize大小后,之后提交的任務(wù)會(huì)被保存到workQueue中,而不是創(chuàng)建新的線程去執(zhí)行它們。當(dāng)workQueue充滿后,就會(huì)去創(chuàng)建新的線程,但是總的線程數(shù)量不會(huì)大于maximumPoolSize

當(dāng)前線程數(shù)量大于corePoolSize的時(shí)候,如果空閑線程等待的時(shí)間超過了keepAliveTime那么這個(gè)空閑線程就會(huì)被銷毀,當(dāng)然如果當(dāng)前線程數(shù)量沒有超過corePoolSize,那么這個(gè)keepAliveTime是不起作用的

常用線程池

newCachedThreadPool

緩存型池子,先查看池中有沒有以前建立的線程,如果有,就reuse,如果沒有,就建立一個(gè)新的線程加入池中。

緩存型池子,通常用于執(zhí)行一些生存周期很短的異步型任務(wù);因此一些面向連接的daemon型server中用得不多。

能reuse的線程,必須是timeout IDLE內(nèi)的池中線程,缺省timeout是60s,超過這個(gè)IDLE時(shí)長(zhǎng),線程實(shí)例將被終止及移出池。

注意,放入CachedThreadPool的線程不必?fù)?dān)心其結(jié)束,超過TIMEOUT不活動(dòng),其會(huì)自動(dòng)被終止。

newFixedThreadPool

newFixedThreadPool與cacheThreadPool差不多,也是能reuse就用,但不能隨時(shí)建新的線程。

其獨(dú)特之處:任意時(shí)間點(diǎn),最多只能有固定數(shù)目的活動(dòng)線程存在,此時(shí)如果有新的線程要建立,只能放在另外的隊(duì)列中等待,直到當(dāng)前的線程中某個(gè)線程終止直接被移出池子。

和cacheThreadPool不同,F(xiàn)ixedThreadPool沒有IDLE機(jī)制(可能也有,但既然文檔沒提,肯定非常長(zhǎng),類似依賴上層的TCP或UDP IDLE機(jī)制之類的),所以FixedThreadPool多數(shù)針對(duì)一些很穩(wěn)定很固定的正規(guī)并發(fā)線程,多用于服務(wù)器。

從方法的源代碼看,cache池和fixed 池調(diào)用的是同一個(gè)底層池,只不過參數(shù)不同:fixed池線程數(shù)固定,并且是0秒IDLE(無IDLE),cache池線程數(shù)支持0-Integer.MAX_VALUE(顯然完全沒考慮主機(jī)的資源承受能力),60秒IDLE 。

ScheduledThreadPool

調(diào)度型線程池。

這個(gè)池子里的線程可以按schedule依次delay執(zhí)行,或周期執(zhí)行。

SingleThreadExecutor

單例線程,任意時(shí)間池中只能有一個(gè)線程。

用的是和cache池和fixed池相同的底層池,但線程數(shù)目是1-1,0秒IDLE(無IDLE)。

多線程 多線程問題生成的原因

線程之間的共享變量存儲(chǔ)在主內(nèi)存(main memory)中,每個(gè)線程都有一個(gè)私有的本地內(nèi)存(local memory),本地內(nèi)存中存儲(chǔ)了該線程以讀/寫共享變量的副本

對(duì)于一個(gè)簡(jiǎn)單的 i++ 操作,會(huì)發(fā)生如下的步驟:

read:作用于主內(nèi)存中,把主內(nèi)存中一個(gè)變量的值傳輸?shù)?工作內(nèi)存 中。

load:作用于工作內(nèi)存,把從read 操作從主內(nèi)存中得到的值放入到工作內(nèi)存的副本中。

use:把工作內(nèi)存中的該副本值傳遞給執(zhí)行引擎(也就是操作數(shù)棧中)。

assign:作用于工作內(nèi)存,把執(zhí)行引擎執(zhí)行后的新值傳遞給該工作內(nèi)存的變量。

store:作用于工作內(nèi)存,把工作內(nèi)存中該變量的值傳送到 主內(nèi)存中去。

write:作用于主內(nèi)存的變量,把store 操作 得到的值寫入到 主內(nèi)存的該變量中。

所以說,一個(gè) i++ 操作并不是原子性的。這上述的這些步驟中,可能會(huì)有其他線程對(duì)主內(nèi)存的變量進(jìn)行操作,從而導(dǎo)致出現(xiàn)多線程問題。

什么是線程安全

線程安全就是說多線程訪問同一代碼,不會(huì)產(chǎn)生不確定的結(jié)果。編寫線程安全的代碼是低依靠線程同步。

線程同步

線程間的通訊首要的方式就是對(duì)字段及其字段所引用的對(duì)象的共享訪問。這種通信方式是及其高效的,但是也是導(dǎo)致了可能的錯(cuò)誤:線程間相互干涉和內(nèi)存一致性的問題。避免出現(xiàn)這兩種錯(cuò)誤的方法就是同步。
線程間相互干擾描述了當(dāng)多個(gè)線程訪問共享數(shù)據(jù)時(shí)可能出現(xiàn)的錯(cuò)誤。
內(nèi)存一致性錯(cuò)誤描述的了共享內(nèi)存可能導(dǎo)致的錯(cuò)誤。
同步方法(Synchronized method)描述了一種簡(jiǎn)單的可以有效防止線程間相互干擾及其內(nèi)存一致性錯(cuò)誤的方法。
明鎖及同步描述了一種更加通用的同步方法,以及同步是如何基于明鎖而實(shí)現(xiàn)的。
原子性描述了不能被其它線程干擾的操作。

Lock和synchronized的選擇

  1. Lock是一個(gè)接口,而synchronized是Java中的關(guān)鍵字,synchronized是內(nèi)置的語言實(shí)現(xiàn)。
  2. synchronized在發(fā)生異常時(shí),會(huì)自動(dòng)釋放線程占有的鎖,因此不會(huì)導(dǎo)致死鎖現(xiàn)象發(fā)生;而Lock在發(fā)生異常時(shí),如果沒有主動(dòng)通過unLock()去釋放鎖,則很可能造成死鎖現(xiàn)象,因此使用Lock時(shí)需要在finally塊中釋放鎖。
  3. Lock可以讓等待鎖的線程響應(yīng)中斷,而synchronized卻不行,使用synchronized時(shí),等待的線程會(huì)一直等待下去,不能夠響應(yīng)中斷。
  4. 通過Lock可以知道有沒有成功獲取鎖,而synchronized卻無法辦到。
  5. Lock可以提高多個(gè)線程進(jìn)行讀操作的效率。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70076.html

相關(guān)文章

  • 集合小記

    摘要:解決沖突開放定址法拉鏈法表解決沖突開放定址法再哈希法鏈地址法建立公共溢出區(qū)并發(fā)包中的線程安全的集合容器線程安全的,不允許為,默認(rèn)個(gè)的數(shù)組,每個(gè)中實(shí)現(xiàn)就是了,通過定位。基于數(shù)組,線程安全的集合類,容量可以限制。 List   List?元素是有序的、可重復(fù),實(shí)現(xiàn)List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。   ArrayList:動(dòng)態(tài)數(shù)組...

    alaege 評(píng)論0 收藏0
  • java基礎(chǔ)小記

    摘要:看到的只是,而由泛型附加的類型信息對(duì)來說是不可見的。然后再加載執(zhí)行類的靜態(tài)變量以及靜態(tài)語句塊。接口中基本數(shù)據(jù)類型為而抽類象不是的。本地方法接口主要是調(diào)用或?qū)崿F(xiàn)的本地方法及返回結(jié)果。用戶自定義類加載器,在程序運(yùn)行期間,通過的子類動(dòng)態(tài)加載。 編譯機(jī)制  編譯主要是把?.Java文件轉(zhuǎn)換為 .class 文件。其中轉(zhuǎn)換后的 .class 文件就包含了元數(shù)據(jù),方法信息等一些信息。比如說元數(shù)據(jù)就...

    ruicbAndroid 評(píng)論0 收藏0
  • 【開發(fā)小記】 Java 線程池 之 被“吃掉”的線程異常(附源碼分析和解決方法)

    摘要:接下來就是會(huì)把任務(wù)提交到隊(duì)列中給線程池調(diào)度處理因?yàn)橹饕P(guān)心的是這個(gè)線程怎么執(zhí)行,異常的拋出和處理,所以我們暫時(shí)不解析多余的邏輯。 前言 今天遇到了一個(gè)bug,現(xiàn)象是,一個(gè)任務(wù)放入線程池中,似乎沒有被執(zhí)行,日志也沒有打。 經(jīng)過本地代碼調(diào)試之后,發(fā)現(xiàn)在任務(wù)邏輯的前半段,拋出了NPE,但是代碼外層沒有try-catch,導(dǎo)致這個(gè)異常被吃掉。 這個(gè)問題解決起來是很簡(jiǎn)單的,外層加個(gè)try-cat...

    Soarkey 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<