1. 程式人生 > >Netty執行緒模型(中)

Netty執行緒模型(中)

1. 背景

1.1. 驚人的效能資料資料分析與企業架構京東618大促下的資料驅動個性化推薦如何構建軟硬體結合的人工智慧產品研發體系中國創新型網際網路企業走向海外的技術機遇與挑戰LinkedIn成員分類平臺大資料應用的最佳實踐
1.2. Netty基礎入門2. Netty高效能之道2.1. RPC呼叫的效能模型分析
      2.1.1. 傳統RPC呼叫效能差的三宗罪
      2.1.2. 高效能的三個主題
2.2. Netty高效能之道
      2.2.1. 非同步非阻塞通訊
      2.2.2. 零拷貝
      2.2.3. 記憶體池
      2.2.4. 高效的Reactor執行緒模型


      2.2.5. 無鎖化的序列設計理念
      2.2.6. 高效的併發程式設計
      2.2.7. 高效能的序列化框架
      2.2.8. 靈活的TCP引數配置能力
2.3. 總結
3. 作者簡介

1. 背景1.1. 驚人的效能資料

最近一個圈內朋友通過私信告訴我,通過使用Netty4 + Thrift壓縮二進位制編解碼技術,他們實現了10W TPS(1K的複雜POJO物件)的跨節點遠端服務呼叫。相比於傳統基於java序列化+BIO(同步阻塞IO)的通訊框架,效能提升了8倍多。

事實上,我對這個資料並不感到驚訝,根據我5年多的NIO程式設計經驗,通過選擇合適的NIO框架,加上高效能的壓縮二進位制編解碼技術,精心的設計Reactor執行緒模型,達到上述效能指標是完全有可能的。

下面我們就一起來看下Netty是如何支援10W TPS的跨節點遠端服務呼叫的,在正式開始講解之前,我們先簡單介紹下Netty。

1.2. Netty基礎入門

Netty是一個高效能、非同步事件驅動的NIO框架,它提供了對TCP、UDP和檔案傳輸的支援,作為一個非同步NIO框架,Netty的所有IO操作都是非同步非阻塞的,通過Future-Listener機制,使用者可以方便的主動獲取或者通過通知機制獲得IO操作結果。

作為當前最流行的NIO框架,Netty在網際網路領域、大資料分散式計算領域、遊戲行業、通訊行業等獲得了廣泛的應用,一些業界著名的開源元件也基於Netty的NIO框架構建。

2. Netty高效能之道
2.1. RPC呼叫的效能模型分析2.1.1. 傳統RPC呼叫效能差的三宗罪

網路傳輸方式問題:傳統的RPC框架或者基於RMI等方式的遠端服務(過程)呼叫採用了同步阻塞IO,當客戶端的併發壓力或者網路時延增大之後,同步阻塞IO會由於頻繁的wait導致IO執行緒經常性的阻塞,由於執行緒無法高效的工作,IO處理能力自然下降。

下面,我們通過BIO通訊模型圖看下BIO通訊的弊端:

圖2-1 BIO通訊模型圖

採用BIO通訊模型的服務端,通常由一個獨立的Acceptor執行緒負責監聽客戶端的連線,接收到客戶端連線之後為客戶端連線建立一個新的執行緒處理請求訊息,處理完成之後,返回應答訊息給客戶端,執行緒銷燬,這就是典型的一請求一應答模型。該架構最大的問題就是不具備彈性伸縮能力,當併發訪問量增加後,服務端的執行緒個數和併發訪問數成線性正比,由於執行緒是JAVA虛擬機器非常寶貴的系統資源,當執行緒數膨脹之後,系統的效能急劇下降,隨著併發量的繼續增加,可能會發生控制代碼溢位、執行緒堆疊溢位等問題,並導致伺服器最終宕機。

序列化方式問題:Java序列化存在如下幾個典型問題:

1) Java序列化機制是Java內部的一種物件編解碼技術,無法跨語言使用;例如對於異構系統之間的對接,Java序列化後的碼流需要能夠通過其它語言反序列化成原始物件(副本),目前很難支援;

2) 相比於其它開源的序列化框架,Java序列化後的碼流太大,無論是網路傳輸還是持久化到磁碟,都會導致額外的資源佔用;

3) 序列化效能差(CPU資源佔用高)。

執行緒模型問題:由於採用同步阻塞IO,這會導致每個TCP連線都佔用1個執行緒,由於執行緒資源是JVM虛擬機器非常寶貴的資源,當IO讀寫阻塞導致執行緒無法及時釋放時,會導致系統性能急劇下降,嚴重的甚至會導致虛擬機器無法建立新的執行緒。

圖2-1 BIO通訊模型圖

採用BIO通訊模型的服務端,通常由一個獨立的Acceptor執行緒負責監聽客戶端的連線,接收到客戶端連線之後為客戶端連線建立一個新的執行緒處理請求訊息,處理完成之後,返回應答訊息給客戶端,執行緒銷燬,這就是典型的一請求一應答模型。該架構最大的問題就是不具備彈性伸縮能力,當併發訪問量增加後,服務端的執行緒個數和併發訪問數成線性正比,由於執行緒是JAVA虛擬機器非常寶貴的系統資源,當執行緒數膨脹之後,系統的效能急劇下降,隨著併發量的繼續增加,可能會發生控制代碼溢位、執行緒堆疊溢位等問題,並導致伺服器最終宕機。

序列化方式問題:Java序列化存在如下幾個典型問題:

1) Java序列化機制是Java內部的一種物件編解碼技術,無法跨語言使用;例如對於異構系統之間的對接,Java序列化後的碼流需要能夠通過其它語言反序列化成原始物件(副本),目前很難支援;

2) 相比於其它開源的序列化框架,Java序列化後的碼流太大,無論是網路傳輸還是持久化到磁碟,都會導致額外的資源佔用;

3) 序列化效能差(CPU資源佔用高)。

執行緒模型問題:由於採用同步阻塞IO,這會導致每個TCP連線都佔用1個執行緒,由於執行緒資源是JVM虛擬機器非常寶貴的資源,當IO讀寫阻塞導致執行緒無法及時釋放時,會導致系統性能急劇下降,嚴重的甚至會導致虛擬機器無法建立新的執行緒。

2.1.2. 高效能的三個主題

1) 傳輸:用什麼樣的通道將資料傳送給對方,BIO、NIO或者AIO,IO模型在很大程度上決定了框架的效能。

2) 協議:採用什麼樣的通訊協議,HTTP或者內部私有協議。協議的選擇不同,效能模型也不同。相比於公有協議,內部私有協議的效能通常可以被設計的更優。

3) 執行緒:資料報如何讀取?讀取之後的編解碼在哪個執行緒進行,編解碼後的訊息如何派發,Reactor執行緒模型的不同,對效能的影響也非常大。

圖2-2 RPC呼叫效能三要素

2.2. Netty高效能之道2.2.1. 非同步非阻塞通訊

在IO程式設計過程中,當需要同時處理多個客戶端接入請求時,可以利用多執行緒或者IO多路複用技術進行處理。IO多路複用技術通過把多個IO的阻塞複用到同一個select的阻塞上,從而使得系統在單執行緒的情況下可以同時處理多個客戶端請求。與傳統的多執行緒/多程序模型比,I/O多路複用的最大優勢是系統開銷小,系統不需要建立新的額外程序或者執行緒,也不需要維護這些程序和執行緒的執行,降低了系統的維護工作量,節省了系統資源。

JDK1.4提供了對非阻塞IO(NIO)的支援,JDK1.5_update10版本使用epoll替代了傳統的select/poll,極大的提升了NIO通訊的效能。

JDK NIO通訊模型如下所示:

圖2-3 NIO的多路複用模型圖

與Socket類和ServerSocket類相對應,NIO也提供了SocketChannel和ServerSocketChannel兩種不同的套接字通道實現。這兩種新增的通道都支援阻塞和非阻塞兩種模式。阻塞模式使用非常簡單,但是效能和可靠性都不好,非阻塞模式正好相反。開發人員一般可以根據自己的需要來選擇合適的模式,一般來說,低負載、低併發的應用程式可以選擇同步阻塞IO以降低程式設計複雜度。但是對於高負載、高併發的網路應用,需要使用NIO的非阻塞模式進行開發。

Netty架構按照Reactor模式設計和實現,它的服務端通訊序列圖如下:

圖2-3 NIO服務端通訊序列圖

客戶端通訊序列圖如下:

圖2-4 NIO客戶端通訊序列圖

Netty的IO執行緒NioEventLoop由於聚合了多路複用器Selector,可以同時併發處理成百上千個客戶端Channel,由於讀寫操作都是非阻塞的,這就可以充分提升IO執行緒的執行效率,避免由於頻繁IO阻塞導致的執行緒掛起。另外,由於Netty採用了非同步通訊模式,一個IO執行緒可以併發處理N個客戶端連線和讀寫操作,這從根本上解決了傳統同步阻塞IO一連線一執行緒模型,架構的效能、彈性伸縮能力和可靠性都得到了極大的提升。

2.2.2. 零拷貝

很多使用者都聽說過Netty具有“零拷貝”功能,但是具體體現在哪裡又說不清楚,本小節就詳細對Netty的“零拷貝”功能進行講解。

Netty的“零拷貝”主要體現在如下三個方面:

1) Netty的接收和傳送ByteBuffer採用DIRECT BUFFERS,使用堆外直接記憶體進行Socket讀寫,不需要進行位元組緩衝區的二次拷貝。如果使用傳統的堆記憶體(HEAP BUFFERS)進行Socket讀寫,JVM會將堆記憶體Buffer拷貝一份到直接記憶體中,然後才寫入Socket中。相比於堆外直接記憶體,訊息在傳送過程中多了一次緩衝區的記憶體拷貝。

2) Netty提供了組合Buffer物件,可以聚合多個ByteBuffer物件,使用者可以像操作一個Buffer那樣方便的對組合Buffer進行操作,避免了傳統通過記憶體拷貝的方式將幾個小Buffer合併成一個大的Buffer。

3) Netty的檔案傳輸採用了transferTo方法,它可以直接將檔案緩衝區的資料傳送到目標Channel,避免了傳統通過迴圈write方式導致的記憶體拷貝問題。

下面,我們對上述三種“零拷貝”進行說明,先看Netty 接收Buffer的建立:

圖2-5 非同步訊息讀取“零拷貝”

每迴圈讀取一次訊息,就通過ByteBufAllocator的ioBuffer方法獲取ByteBuf物件,下面繼續看它的介面定義:

圖2-6 ByteBufAllocator 通過ioBuffer分配堆外記憶體

當進行Socket IO讀寫的時候,為了避免從堆記憶體拷貝一份副本到直接記憶體,Netty的ByteBuf分配器直接建立非堆記憶體避免緩衝區的二次拷貝,通過“零拷貝”來提升讀寫效能。

下面我們繼續看第二種“零拷貝”的實現CompositeByteBuf,它對外將多個ByteBuf封裝成一個ByteBuf,對外提供統一封裝後的ByteBuf介面,它的類定義如下:

圖2-7 CompositeByteBuf類繼承關係

通過繼承關係我們可以看出CompositeByteBuf實際就是個ByteBuf的包裝器,它將多個ByteBuf組合成一個集合,然後對外提供統一的ByteBuf介面,相關定義如下:

圖2-8 CompositeByteBuf類定義

新增ByteBuf,不需要做記憶體拷貝,相關程式碼如下:

圖2-9 新增ByteBuf的“零拷貝”

最後,我們看下檔案傳輸的“零拷貝”:

圖2-10 檔案傳輸“零拷貝”

Netty檔案傳輸DefaultFileRegion通過transferTo方法將檔案傳送到目標Channel中,下面重點看FileChannel的transferTo方法,它的API DOC說明如下:

圖2-11 檔案傳輸 “零拷貝”

對於很多作業系統它直接將檔案緩衝區的內容傳送到目標Channel中,而不需要通過拷貝的方式,這是一種更加高效的傳輸方式,它實現了檔案傳輸的“零拷貝”。

2.2.3. 記憶體池

隨著JVM虛擬機器和JIT即時編譯技術的發展,物件的分配和回收是個非常輕量級的工作。但是對於緩衝區Buffer,情況卻稍有不同,特別是對於堆外直接記憶體的分配和回收,是一件耗時的操作。為了儘量重用緩衝區,Netty提供了基於記憶體池的緩衝區重用機制。下面我們一起看下Netty ByteBuf的實現:

圖2-12 記憶體池ByteBuf

Netty提供了多種記憶體管理策略,通過在啟動輔助類中配置相關引數,可以實現差異化的定製。

下面通過效能測試,我們看下基於記憶體池迴圈利用的ByteBuf和普通ByteBuf的效能差異。

用例一,使用記憶體池分配器建立直接記憶體緩衝區:

圖2-13 基於記憶體池的非堆記憶體緩衝區測試用例

用例二,使用非堆記憶體分配器建立的直接記憶體緩衝區:

圖2-14 基於非記憶體池建立的非堆記憶體緩衝區測試用例

各執行300萬次,效能對比結果如下所示:

 

圖2-15 記憶體池和非記憶體池緩衝區寫入效能對比

效能測試表明,採用記憶體池的ByteBuf相比於朝生夕滅的ByteBuf,效能高23倍左右(效能資料與使用場景強相關)。

下面我們一起簡單分析下Netty記憶體池的記憶體分配:

圖2-16 AbstractByteBufAllocator的緩衝區分配

繼續看newDirectBuffer方法,我們發現它是一個抽象方法,由AbstractByteBufAllocator的子類負責具體實現,程式碼如下:

圖2-17 newDirectBuffer的不同實現

程式碼跳轉到PooledByteBufAllocator的newDirectBuffer方法,從Cache中獲取記憶體區域PoolArena,呼叫它的allocate方法進行記憶體分配:

圖2-18 PooledByteBufAllocator的記憶體分配

PoolArena的allocate方法如下:

圖2-19 PoolArena的newByteBuf抽象方法

因此重點分析DirectArena的實現:如果沒有開啟使用sun的unsafe,則

圖2-20 DirectArena的newByteBuf方法實現

執行PooledDirectByteBuf的newInstance方法,程式碼如下:

圖2-21 PooledDirectByteBuf的newInstance方法實現

通過RECYCLER的get方法迴圈使用ByteBuf物件,如果是非記憶體池實現,則直接建立一個新的ByteBuf物件。從緩衝池中獲取ByteBuf之後,呼叫AbstractReferenceCountedByteBuf的setRefCnt方法設定引用計數器,用於物件的引用計數和記憶體回收(類似JVM垃圾回收機制)。

2.2.4. 高效的Reactor執行緒模型

常用的Reactor執行緒模型有三種,分別如下:

1) Reactor單執行緒模型;

2) Reactor多執行緒模型;

3) 主從Reactor多執行緒模型

Reactor單執行緒模型,指的是所有的IO操作都在同一個NIO執行緒上面完成,NIO執行緒的職責如下:

1) 作為NIO服務端,接收客戶端的TCP連線;

2) 作為NIO客戶端,向服務端發起TCP連線;

3) 讀取通訊對端的請求或者應答訊息;

4) 向通訊對端傳送訊息請求或者應答訊息。

Reactor單執行緒模型示意圖如下所示:

圖2-22 Reactor單執行緒模型

由於Reactor模式使用的是非同步非阻塞IO,所有的IO操作都不會導致阻塞,理論上一個執行緒可以獨立處理所有IO相關的操作。從架構層面看,一個NIO執行緒確實可以完成其承擔的職責。例如,通過Acceptor接收客戶端的TCP連線請求訊息,鏈路建立成功之後,通過Dispatch將對應的ByteBuffer派發到指定的Handler上進行訊息解碼。使用者Handler可以通過NIO執行緒將訊息傳送給客戶端。

對於一些小容量應用場景,可以使用單執行緒模型。但是對於高負載、大併發的應用卻不合適,主要原因如下:

1) 一個NIO執行緒同時處理成百上千的鏈路,效能上無法支撐,即便NIO執行緒的CPU負荷達到100%,也無法滿足海量訊息的編碼、解碼、讀取和傳送;

2) 當NIO執行緒負載過重之後,處理速度將變慢,這會導致大量客戶端連線超時,超時之後往往會進行重發,這更加重了NIO執行緒的負載,最終會導致大量訊息積壓和處理超時,NIO執行緒會成為系統的效能瓶頸;

3) 可靠性問題:一旦NIO執行緒意外跑飛,或者進入死迴圈,會導致整個系統通訊模組不可用,不能接收和處理外部訊息,造成節點故障。

為了解決這些問題,演進出了Reactor多執行緒模型,下面我們一起學習下Reactor多執行緒模型。

Rector多執行緒模型與單執行緒模型最大的區別就是有一組NIO執行緒處理IO操作,它的原理圖如下:

圖2-23 Reactor多執行緒模型

Reactor多執行緒模型的特點:

1) 有專門一個NIO執行緒-Acceptor執行緒用於監聽服務端,接收客戶端的TCP連線請求;

2) 網路IO操作-讀、寫等由一個NIO執行緒池負責,執行緒池可以採用標準的JDK執行緒池實現,它包含一個任務佇列和N個可用的執行緒,由這些NIO執行緒負責訊息的讀取、解碼、編碼和傳送;

3) 1個NIO執行緒可以同時處理N條鏈路,但是1個鏈路只對應1個NIO執行緒,防止發生併發操作問題。

在絕大多數場景下,Reactor多執行緒模型都可以滿足效能需求;但是,在極特殊應用場景中,一個NIO執行緒負責監聽和處理所有的客戶端連線可能會存在效能問題。例如百萬客戶端併發連線,或者服務端需要對客戶端的握手訊息進行安全認證,認證本身非常損耗效能。在這類場景下,單獨一個Acceptor執行緒可能會存在效能不足問題,為了解決效能問題,產生了第三種Reactor執行緒模型-主從Reactor多執行緒模型。

主從Reactor執行緒模型的特點是:服務端用於接收客戶端連線的不再是個1個單獨的NIO執行緒,而是一個獨立的NIO執行緒池。Acceptor接收到客戶端TCP連線請求處理完成後(可能包含接入認證等),將新建立的SocketChannel註冊到IO執行緒池(sub reactor執行緒池)的某個IO執行緒上,由它負責SocketChannel的讀寫和編解碼工作。Acceptor執行緒池僅僅只用於客戶端的登陸、握手和安全認證,一旦鏈路建立成功,就將鏈路註冊到後端subReactor執行緒池的IO執行緒上,由IO執行緒負責後續的IO操作。

它的執行緒模型如下圖所示:

圖2-24 Reactor主從多執行緒模型

利用主從NIO執行緒模型,可以解決1個服務端監聽執行緒無法有效處理所有客戶端連線的效能不足問題。因此,在Netty的官方demo中,推薦使用該執行緒模型。

事實上,Netty的執行緒模型並非固定不變,通過在啟動輔助類中建立不同的EventLoopGroup例項並通過適當的引數配置,就可以支援上述三種Reactor執行緒模型。正是因為Netty 對Reactor執行緒模型的支援提供了靈活的定製能力,所以可以滿足不同業務場景的效能訴求。

2.2.5. 無鎖化的序列設計理念

在大多數場景下,並行多執行緒處理可以提升系統的併發效能。但是,如果對於共享資源的併發訪問處理不當,會帶來嚴重的鎖競爭,這最終會導致效能的下降。為了儘可能的避免鎖競爭帶來的效能損耗,可以通過序列化設計,即訊息的處理儘可能在同一個執行緒內完成,期間不進行執行緒切換,這樣就避免了多執行緒競爭和同步鎖。

為了儘可能提升效能,Netty採用了序列無鎖化設計,在IO執行緒內部進行序列操作,避免多執行緒競爭導致的效能下降。表面上看,序列化設計似乎CPU利用率不高,併發程度不夠。但是,通過調整NIO執行緒池的執行緒引數,可以同時啟動多個序列化的執行緒並行執行,這種區域性無鎖化的序列執行緒設計相比一個佇列-多個工作執行緒模型效能更優。

Netty的序列化設計工作原理圖如下:

圖2-25 Netty序列化工作原理圖

Netty的NioEventLoop讀取到訊息之後,直接呼叫ChannelPipeline的fireChannelRead(Object msg),只要使用者不主動切換執行緒,一直會由NioEventLoop呼叫到使用者的Handler,期間不進行執行緒切換,這種序列化處理方式避免了多執行緒操作導致的鎖的競爭,從效能角度看是最優的。

相關推薦

Netty執行模型

1. 背景 1.1. 驚人的效能資料資料分析與企業架構京東618大促下的資料驅動個性化推薦如何構建軟硬體結合的人工智慧產品研發體系中國創新型網際網路企業走向海外的技術機遇與挑戰LinkedIn成員分類平臺大資料應用的最佳實踐1.2. Netty基礎入門2. Net

netty原始碼分析之-EventLoop與執行模型1

執行緒模型確定來程式碼的執行方式,我們總是必須規避併發執行可能會帶來的副作用,所以理解netty所採用的併發模型的影響很重要。netty使用了被稱為事件迴圈的EventLoop來執行任務來處理在連線的生命週期內發生的事件 執行緒模型 對於Even

Chrome原始碼分析之程序和執行模型

關於Chrome的執行緒模型,在他的開發文件中有專門的介紹,原文地址在這裡:http://dev.chromium.org/developers/design-documents/threading chrome的程序,chrome沒有采用一般應用程式的單程序多執行緒的模

C#淺談執行:獨立執行池的作用及IO執行

在上一篇文章中,我們簡單討論了執行緒池的作用,以及CLR執行緒池的一些特性。不過關於執行緒池的基本概念還沒有結束,這次我們再來補充一些必要的資訊,有助於我們在程式中選擇合適的使用方式。 獨立執行緒池 上次我們討論到,在一個.NET應用程式中會有一個CLR執行緒池,可以使用Th

Netty的Channel之資料沖刷與執行安全writeAndFlush

本文首發公眾號與個人部落格:Java貓說 & 貓叔的部落格 | MySelf,轉載請申明出處。 GitHub專案地址 InChat 一個輕量級、高效率的支援多端(應用與硬體Iot)的非同步網路應用通訊框架 前言 本文預設讀者已經瞭解了一定的Netty基礎

Netty原始碼死磕一netty執行模型及EventLoop機制

## 引言 好久沒有寫部落格了,近期準備把`Netty`原始碼啃一遍。在這之前本想直接看原始碼,但是看到後面發現其實效率不高, 有些概念還是有必要回頭再細啃的,特別是其執行緒模型以及`EventLoop`的概念。 當然在開始之前還是有務必要對`IO模型`要有清晰準確的認識。 傳送門 []() ## 事件

Java多執行學習JUC 的 Atomic 原子類總結

阿里雲產品 1888 代金券領取:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=hf47liqn 本節思維導圖: 1 Atomic 原子類介紹 Atomic 翻譯成中文是原

VS的多執行/MT、多執行除錯/MTd、多執行DLL/MD、多執行除錯DLL/MDd的區別

一種語言的開發環境往往會附帶有語言庫,這些庫就是對作業系統的API的包裝,我們也稱這些語言庫為執行庫 對於MSVC的執行庫(CRT),按照靜態/動態連結,可以分為靜態版和動態版;按照除錯/釋出,可以分為除錯版本和釋出版本;按照單執行緒/多執行緒,可以分為單執行緒版本和多執行

基本執行同步在Lock使用多個條件

宣告:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     譯者:許巧輝 校對:方騰飛 在Lock中使用多個條件 一個鎖可能伴隨著多個條件。這些條件宣告在Condition介面中。 這些條件的目的是允許

基本執行同步在同步程式碼使用條件

宣告:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González     譯者:許巧輝 校對:方騰飛 在同步程式碼中使用條件 在併發程式設計中的一個經典問題是生產者與消費者問題,我們有一個數據緩衝區,一個或多個數據的

Java多執行程式設計-14-無鎖CAS操作以及JavaAtomic併發包的“18羅漢”

原文出自 : https://blog.csdn.net/xlgen157387/article/details/78364246 上一篇: Java多執行緒程式設計-(13)- 關於鎖優化的幾點建議 一、背景 通過上面的學習,我們應該很清楚的

Java多執行程式設計-12-Java的佇列同步器AQS和ReentrantLock鎖原理簡要分析

原文出自 : https://blog.csdn.net/xlgen157387/article/details/78341626 一、Lock介面 在上一篇文章中: Java多執行緒程式設計-(5)-使用Lock物件實現同步以及執行緒間通訊 介紹

Java執行2——執行的幾個重要方法詳解

【內容摘要】 在java中,如果需要進行多執行緒程式設計,可以採用java自帶的執行緒池來實現,執行緒池對於我們新手來說是一個非常好的選擇,因為我們可以不用關心執行緒池中執行緒是如何排程的,避免在多執行緒程式設計過程產生死鎖等問題。在瞭解執行緒池的使用前,本文

Java執行安全synchronized

package tk.javazhangwei.thread.syn; /*** * 執行緒安全問題 * * @author zw * */ public class SynDemo01 { public static void main(String[]

Android執行執行“getevent”命令時的執行退出結束問題

       專案中遇到需要執行shell命令“getevent”獲取座標引數的需求,但是發現無法結束執行該命令的執行緒,後來終於發現解決方法。在此記錄下。        我線上程中通過Process

JAVA多執行入門:JAVA如何寫多執行

第一種方式:繼承Thread 步驟: 1.建立執行緒類,繼承自Thread + 重寫run,run中寫執行緒體,執行緒體就是mian()函式裡面的寫法 2.使用執行緒: 2.1 建立執行緒物件 2.2 執行緒物件.start() 步驟展示: 1. public

java執行筆記

java對多執行緒程式設計提供了內建支援。多執行緒程式包含同時執行的兩個或多個部分。這種程式的每一部分被稱為一個執行緒,並且每一個執行緒定義了單獨的執行路徑。因此,多執行緒是特殊形式的多工處理。 程序:正在進行中的程式,是重量級任務,需要自己的地址空間。程序間通訊開銷很大,

Java多執行執行安全0Java記憶體區域與Java記憶體模型

概況 本文內容 1.Java記憶體區域劃分 2.Java記憶體模型JMM 3.硬體記憶體架構與Java記憶體模型 4.Jvm中執行緒實現機制 5.執行緒安全問題的原因 一.理解Java記憶體區域與Java記憶體模型 看

【多執行】檢視JVM執行ThreadGroup

ThreadGroup類的常用方法activeCount()——返回此執行緒組中活動執行緒的估計數activeGroupCount()——返回此執行緒組中活動執行緒組的估計數enumerate(Thread[] list,boolean recurse)——把此執行緒組中所有

Android多執行View.post()原始碼分析——在子執行更新UI

       提起View.post(),相信不少童鞋一點都不陌生,它用得最多的有兩個功能,使用簡便而且實用:        1)在子執行緒中更新UI。從子執行緒中切換到主執行緒更新UI,不需要額外new一個Handler例項來實