文章編號:11436時間:2024-09-30人氣:
在 Java 中,
suspendThread
方法曾用于暫停線程的執行。由于存在許多缺點,該方法已于 JDK 9 中被棄用。
本文將介紹一種更現代的線程同步機制——線程同步屏障(barrier),它提供了類似于
suspendThread
的暫停線程功能,但具有更好的可靠性和安全性。
線程同步屏障是一種同步原語,它允許線程組中的所有線程等待,直到所有線程都到達指定屏障點。
線程同步屏障有以下特點:
要使用線程同步屏障,需要創建
CyclicBarrier
對象。
CyclicBarrier
的構造函數需要一個整數參數,表示要等待的線程數。
每個線程都可以調用
await()
方法來等待屏障點。當所有線程都調用了
await()
方法,屏障點將被解除,所有線程將繼續執行。
以下代碼示例展示了如何使用線程同步屏障:
import java.util.concurrent.CyclicBarrier;public class ThreadSyncBarrierExample {public static void main(String[] args) {
// 創建一個CyclicBarrier對象,等待5個線程CyclicBarrier barrier = new CyclicBarrier(5);// 創建5個線程并啟動它們for (int i = 0; i < 5; i++) {new Thread(() -> {try {// 線程等待屏障點barrier.await();// 屏障點被解除后,繼續執行System.out.println("線程 " + Thread.currentThread().getName() + " 已通過屏障點");} catch (Exception e) {e.printStackTrace();}}).start();}}}
線程同步屏障比
suspendThread
具有以下優點:
suspendThread
可能會導致死鎖,而線程同步屏障不會。
suspendThread
可以在任何時候被中斷。
suspendThread
的釋放順序是不確定的。
線程同步屏障還提供了更多高級功能,例如超時和中斷機制,這使得它在對線程控制有更嚴格要求的場景中更加有用。
線程同步屏障是一種更現代、更安全的替代方案,用于替代棄用的
suspendThread
方法。它提供了一致且可預測的線程同步機制,非常適合需要精確控制線程執行順序的場景。
這個函數是主要用于調試器。 它并不打算用于線程同步。 在一個線程調用SuspendThread擁有一個同步對象,比如互斥或關鍵部分,會導致死鎖如果調用線程試圖獲取同步對象屬于一個暫停的線程。 為了避免這種情況,一個線程在一個應用程序,它不是一個調試器應該信號其他線程暫停本身
暫停線程執行的API函數是SuspendThread,聲明如下:DWORD SuspendThread(HANDLEhThread);其中,參數hThread是要暫停的線程句柄,該句柄必須要有THREAD SUSPEND RESUME訪問權限。 如果函數成功就返回以前暫停的次數,否則返回-1,此時可以用GetLastError來獲得錯誤碼。 當函數成功的時候,線程將暫停執行,并且線程的暫停次數遞增一次。 每個線程都有一個暫停計數器,最大值為MAXIMUMSUSPENDCOUNT,如果暫停計數器大于零,線程則暫停執行。 另外,這個函數一般不用于線程同步,如果對一個擁有同步對象(比如信號量或臨界區)的線程調用SuspendThread函數,則有可能會引起死鎖,尤其當被暫停的線程想要獲取同步對象的時候。 恢復線程執行的函數是ResumeThread,但不是說調用該函數線程就會恢復執行,該函數主要是減少暫停計數器的次數。 線程的暫停計數器如果恢復到零,線程才會恢復執行。 暫停線程執行的API函數是SuspendThread,聲明如下:DWORD SuspendThread(HANDLEhThread);其中,參數hThread是要暫停的線程句柄,該句柄必須要有THREAD SUSPEND RESUME訪問權限。 如果函數成功就返回以前暫停的次數,否則返回-1,此時可以用GetLastError來獲得錯誤碼。 當函數成功的時候,線程將暫停執行,并且線程的暫停次數遞增一次。 每個線程都有一個暫停計數器,最大值為MAXIMUMSUSPENDCOUNT,如果暫停計數器大于零,線程則暫停執行。 另外,這個函數一般不用于線程同步,如果對一個擁有同步對象(比如信號量或臨界區)的線程調用SuspendThread函數,則有可能會引起死鎖,尤其當被暫停的線程想要獲取同步對象的時候。 恢復線程執行的函數是ResumeThread,但不是說調用該函數線程就會恢復執行,該函數主要是減少暫停計數器的次數。 線程的暫停計數器如果恢復到零,線程才會恢復執行。
在windows下做服務器最好的方案是IOCP(I/O Complete port),中文名I/O完成端口性能很不錯。 涉及windows高級編程,難學指數比較高你的的感覺很不錯,這個方案不可行:1.會浪費大量CPU時間。 一臺計算機CPU個數有限,如果你的計算機只有2個CPU,卻開了200線程。 這個時候在同一時間,最多有2個線程在運行(因為你只有2個CPU),但是線程的不斷切換讓你感覺好像200個都在運行,只不過速度很慢。 (此時線程切換會耗掉大量CPU時間,得不償失)。 2.浪費內存。 線程在windows中需要用數據表示,200個線程,開銷有點浪費(雖然現在內存都很大,但是我們不能浪費)3.線程同步問題會讓你暈掉的,200個線程并發處理是很麻煩的,要進行線程同步,以及線程通信,同步和通信是多線程必須深思熟慮的。 4.有一個很不錯的解決方案---IOCP關于IOCP的學習,網上資料很多在此不多言。 enjoy coding
線程的同步是Java多線程編程的難點,往往開發者搞不清楚什么是競爭資源、什么時候需要考慮同步,怎么同步等等問題,當然,這些問題沒有很明確的答案,但有些原則問題需要考慮,是否有競爭資源被同時改動的問題?對于同步,在具體的Java代碼中需要完成以下兩個操作:把競爭訪問的資源標識為private;同步哪些修改變量的代碼,使用synchronized關鍵字同步方法或代碼。
當然這不是唯一控制并發安全的途徑。
synchronized關鍵字使用說明synchronized只能標記非抽象的方法,不能標識成員變量。
為了演示同步方法的使用,構建了一個信用卡賬戶,起初信用額為100w,然后模擬透支、存款等多個操作。
顯然銀行賬戶User對象是個競爭資源,而多個并發操作的是賬戶方法oper(int x),當然應該在此方法上加上同步,并將賬戶的余額設為私有變量,禁止直接訪問。
工作原理線程是進程中的實體,一個進程可以擁有多個線程,一個線程必須有一個父進程。
線程不擁有系統資源,只有運行必須的一些數據結構;它與父進程的其它線程共享該進程所擁有的全部資源。
線程可以創建和撤消線程,從而實現程序的并發執行。
一般,線程具有就緒、阻塞和運行三種基本狀態。
在多中央處理器的系統里,不同線程可以同時在不同的中央處理器上運行,甚至當它們屬于同一個進程時也是如此。
大多數支持多處理器的操作系統都提供編程接口來讓進程可以控制自己的線程與各處理器之間的關聯度(affinity)。
有時候,線程也稱作輕量級進程。
就象進程一樣,線程在程序中是獨立的、并發的執行路徑,每個線程有它自己的堆棧、自己的程序計數器和自己的局部變量。
但是,與分隔的進程相比,進程中的線程之間的隔離程度要小。
它們共享內存、文件句柄和其它每個進程應有的狀態。
進程可以支持多個線程,它們看似同時執行,但互相之間并不同步。
一個進程中的多個線程共享相同的內存地址空間,這就意味著它們可以訪問相同的變量和對象,而且它們從同一堆中分配對象。
盡管這讓線程之間共享信息變得更容易,但您必須小心,確保它們不會妨礙同一進程里的其它線程。
Java 線程工具和 API看似簡單。
但是,編寫有效使用線程的復雜程序并不十分容易。
因為有多個線程共存在相同的內存空間中并共享相同的變量,所以您必須小心,確保您的線程不會互相干擾。
線程屬性為了正確有效地使用線程,必須理解線程的各個方面并了解Java 實時系統。
必須知道如何提供線程體、線程的生命周期、實時系統如 何調度線程、線程組、什么是幽靈線程(Demo nThread)。
線程體所有的操作都發生在線程體中,在Java中線程體是從Thread類繼承的run()方法,或實現Runnable接口的類中的run()方法。
當線程產生并初始化后,實時系統調用它的run()方法。
run()方法內的代碼實現所產生線程的行為,它是線程的主要部分。
線程狀態附圖表示了線程在它的生命周期內的任何時刻所能處的狀態以及引起狀態改變的方法。
這圖并不是完整的有限狀態圖,但基本概括了線程中比較感興趣和普遍的方面。
以下討論有關線程生命周期以此為據。
●新線程態(New Thread)產生一個Thread對象就生成一個新線程。
當線程處于新線程狀態時,僅僅是一個空線程對象,它還沒有分配到系統資源。
因此只能啟動或終止它。
任何其他操作都會引發異常。
例如,一個線程調用了new方法之后,并在調用start方法之前的處于新線程狀態,可以調用start和stop方法。
●可運行態(Runnable)start()方法產生運行線程所必須的資源,調度線程執行,并且調用線程的run()方法。
在這時線程處于可運行態。
該狀態不稱為運行態是因為這時的線程并不總是一直占用處理機。
特別是對于只有一個處理機的PC而言,任何時刻只能有一個處于可運行態的線程占用處理 機。
Java通過調度來實現多線程對處理機的共享。
注意,如果線程處于Runnable狀態,它也有可能不在運行,這是因為還有優先級和調度問題。
●阻塞/非運行態(Not Runnable)當以下事件發生時,線程進入非運行態。
①suspend()方法被調用;②sleep()方法被調用;③線程使用wait()來等待條件變量;④線程處于I/O請求的等待。
●死亡態(Dead)當run()方法返回,或別的線程調用stop()方法,線程進入死亡態。
通常Applet使用它的stop()方法來終止它產生的所有線程。
線程的本操作:派生:線程在進程內派生出來,它即可由進程派生,也可由線程派生。
阻塞(Block):如果一個線程在執行過程中需要等待某個事件發生,則被阻塞。
激活(unblock):如果阻塞線程的事件發生,則該線程被激活并進入就緒隊列。
調度(schedule):選擇一個就緒線程進入執行狀態。
結束(Finish):如果一個線程執行結束,它的寄存器上下文以及堆棧內容等將被釋放。
圖2 線程的狀態與操作線程的另一個執行特性是同步。
線程中所使用的同步控制機制與進程中所使用的同步控制機制相同。
線程優先級雖然我們說線程是并發運行的。
然而事實常常并非如此。
正如前面談到的,當系統中只有一個CPU時,以某種順序在單CPU情況下執行多線程被稱為調度(scheduling)。
Java采用的是一種簡單、固定的調度法,即固定優先級調度。
這種算法是根據處于可運行態線程的相對優先級來實行調度。
當線程產生時,它繼承原線程的優先級。
在需要時可對優先級進行修改。
在任何時刻,如果有多條線程等待運行,系統選擇優先級最高的可運行線程運行。
只有當它停止、自動放棄、或由于某種原因成為非運行態低優先級的線程才能運行。
如果兩個線程具有相同的優先級,它們將被交替地運行。
Java實時系統的線程調度算法還是強制性的,在任何時刻,如果一個比其他線程優先級都高的線程的狀態變為可運行態,實時系統將選擇該線程來運行。
一個應用程序可以通過使用線程中的方法setPriority(int),來設置線程的優先級大小。
有線程進入了就緒狀態,需要有線程調度程序來決定何時執行,根據優先級來調度。
線程中的join()可以用來邀請其他線程先執行(示例代碼如下);publicclassJoin01implementsRunnable{publicstaticvoidmain(String[]args){for(inti=0;i<20;i++){if(i==5){Join01j=newJoin01();Threadt=newThread(j);(被邀請先執行的線程.);();try{//邀請這個線程,先執行();}catch(InterruptedExceptione){();}}(沒被邀請的線程。
+(i+1));}}publicvoidrun(){for(inti=0;i<10;i++){(()()+(i+1));}}}yield()告訴系統把自己的CPU時間讓掉,讓其他線程或者自己運行,示例代碼如下;publicclassYield01{publicstaticvoidmain(String[]args){YieldFirstyf=newYieldFirst();YieldSecondys=newYieldSecond();YieldThirdyt=newYieldThird();();();();}}classYieldFirstextendsThread{@Overridepublicvoidrun(){for(inti=0;i<10;i++){(第一個線程第+(i+1)+次運行.);//讓當前線程暫停yield();}}}classYieldSecondextendsThread{@Overridepublicvoidrun(){for(inti=0;i<10;i++){(第二個線程第+(i+1)+次運行.);//讓當前線程暫停yield(); ,僅適用于Sun Solaris操作系統。
所以UNIX International線程也常被俗稱為Solaris線程。
1.創建線程intthr_create(void*stack_base,size_tstack_size,void*(*start_routine)(void*),void*arg,longflags,thread_t*new_thr);2.等待線程intthr_join(thread_twait_for,thread_t*dead,void**status);3.掛起線程intthr_suspend(thread_tthr);4.繼續線程intthr_continue(thread_tthr);5.退出線程voidthr_exit(void*status);6.返回當前線程的線程標識符thread_tthr_self(void);POSIX線程POSIX線程(Pthreads)的頭文件是
內容聲明:
1、本站收錄的內容來源于大數據收集,版權歸原網站所有!
2、本站收錄的內容若侵害到您的利益,請聯系我們進行刪除處理!
3、本站不接受違法信息,如您發現違法內容,請聯系我們進行舉報處理!
4、本文地址:http://m.sycxjdsbhs.com/article/e8693fa6a7b84d79f3a0.html,復制請保留版權鏈接!
簡介Silverlight是一種Microsoft開發的跨瀏覽器、跨平臺插件,用于創建豐富的、交互式的Web應用程序,它基于.NETFramework,并提供一系列功能來增強網站用戶體驗,Silverlight網站開發的優勢豐富而生動的用戶界面,Silverlight支持3D圖形、動畫、視頻和音頻,能夠創建引人入勝的、沉浸式的用戶界面...。
互聯網資訊 2024-09-30 02:34:16
簡介HttpClientJar是一個Java庫,用于管理HTTPCookie和會話,它提供了一個統一的界面來處理不同類型的HTTP庫中的Cookie和會話,使其成為管理HTTP會話的寶貴工具,安裝HttpClientJar可以通過MavenCentral倉庫進行安裝,```xmlcom.github.daniel,shuyhttpcl...。
技術教程 2024-09-26 18:15:44
數學長期以來一直是科學和技術進步的基礎,但傳統數學存在一定的局限性,數棧是一種革命性的數字系統,它超越了這些限制,為數學開辟了新的可能性,數棧的原理數棧是由數學家約翰·康威在1980年代發明的,是一種基于堆棧的數學系統,每個數棧都是一個有序的數學對象的序列,這些對象可以是數字、函數或其他數學結構,數棧的基本操作是壓棧,push,和出棧...。
互聯網資訊 2024-09-26 01:54:04
文章內容...文章內容...文章內容...小標題1小標題1相關的內容...小標題1相關的內容...小標題2小標題2相關的內容...小標題2相關的內容...示例列表列表項1列表項2列表項3示例表格表頭1表頭2表頭3單元格1,1單元格1,2單元格1,3單元格2,1單元格2,2單元格2,3示例代碼塊代碼塊內容...示例引用引文內容......。
本站公告 2024-09-24 01:55:33
OSGi,開放服務網關倡議,是一個用于開發模塊化、可重用的Java組件的標準,它為構建可靈活擴展和適應不斷變化需求的復雜系統提供了框架,OSGi的優勢模塊化,OSGi組件可以獨立開發和部署,從而提高代碼可重用性和維護性,可擴展性,OSGi架構允許動態添加和移除組件,而無需重新啟動整個系統,松散耦合,OSGi組件通過服務接口松散耦合,促...。
技術教程 2024-09-23 14:27:46
簡介在Web開發中,下拉列表,DropdownList,是一種常見的控件,允許用戶從一系列預定義選項中選擇一個,當用戶與下拉列表交互時,會觸發各種事件,理解這些事件并對其進行恰當處理對于創建響應式且易于使用的Web應用程序至關重要,事件類型以下是在使用下拉列表時會觸發的事件,SelectedIndexChanged,當用戶更改下拉列表...。
最新資訊 2024-09-15 15:25:42
什么是內連接,內連接是一種SQL連接,用于從兩個表中選擇滿足特定條件的行,它僅返回兩個表中具有匹配行的記錄,所有其他行都會被忽略,內連接的陷阱1.丟失行內連接最常見的陷阱是丟失行,當連接條件不滿足時,內連接將過濾掉整個行,即使該行在其他表中可能存在匹配項,這可能導致丟失重要數據,SELECTFROMtable1INNERJOINtab...。
最新資訊 2024-09-14 22:46:06
分布式鎖在分布式系統中,多個進程或線程可能試圖同時訪問共享資源,這可能導致數據損壞或其他問題,為了防止這種情況,我們可以使用分布式鎖,分布式鎖是一種機制,它允許進程或線程獲取對共享資源的獨占訪問權,一旦進程或線程獲得了鎖,它就可以訪問資源,而其他進程或線程將被阻止訪問,有許多不同的分布式鎖實現方式,最常見的方法之一是使用分布式協調服務...。
技術教程 2024-09-10 19:10:10
什么是織夢之家,織夢之家是織夢內容管理系統,CMS,的官方網站,為織夢用戶提供全面的服務和支持,織夢之家有哪些服務,官方論壇,提供技術支持、使用技巧交流和社區互動,技術文檔,詳細的織夢系統使用說明和技術文檔,插件市場,豐富的織夢插件和模版資源,在線課程,專業的織夢系統教程和培訓,官方微博,發布最新動態、產品信息和行業資訊,織夢之家可以...。
最新資訊 2024-09-09 21:50:31
在電子商務網站上,客戶經常需要刷新頁面才能看到更新后的信息,例如購物車中的商品數量或價格的變化,這通常是一個令人沮喪的過程,特別是當客戶正在趕時間或嘗試完成購買的時候,幸運的是,使用JavaScript,我們可以進行無痛刷新,可以瞬間更新頁面,而無需客戶刷新,這可以極大地提高客戶體驗,并有助于提高轉化率,如何進行無痛刷新要實現無痛刷新...。
本站公告 2024-09-09 14:06:30
Oracle數據庫是業界領先的關系型數據庫管理系統,廣泛用于各種規模的組織,無論你是初學者還是經驗豐富的數據庫專業人員,本指南將提供一個全面的分步指南,指導你下載和安裝Oracle數據庫,對于初學者第1步,訪問Oracle下載頁面在瀏覽器中訪問Oracle技術網絡,OTN,網站,https,www.oracle.com,techn...。
技術教程 2024-09-09 08:23:42
Java接口概述Java接口是一種抽象類型,它定義了一組方法簽名,但不包含任何實現,接口用于為類指定契約,而無需指定其實現細節,接口在Java中扮演著至關重要的角色,它們提供了一種實現抽象和解耦的方法,通過強制類實現接口,您可以確保它們提供特定功能,而無需關心這些功能是如何實現的,接口的優點抽象,接口允許您創建抽象類層次結構,其中子類...。
本站公告 2024-09-08 12:30:22