為什麼實現線程同步的?
為什麼要線程同步,說出線程同步的幾種方法
線程有可能和其他線程共享一些資源,比如,內存,文件,數據庫等。
當多個線程同時讀寫同一份共享資源的時候,可能會引起衝突。這時候,我們需要引入線程“同步”機制,即各位線程之間要有個先來後到,不能一窩蜂擠上去搶作一團。
線程同步的真實意思和字面意思恰好相反。線程同步的真實意思,其實是“排隊”:幾個線程之間要排隊,一個一個對共享資源進行操作,而不是同時進行操作。
線程同盯的方法
(1)wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
(2)sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉
InterruptedException異常。
(3)notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的
喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
(4)notityAll ():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,
而是讓它們競爭
如何實現多個線程同步
同步的實現方面有兩種,分別是synchronized,wait與notify wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先級。
Allnotity():喚醒所有處入等待狀態的線程。
線程同步的幾種方法的總結
線程同步的方式包括:互斥鎖、讀寫鎖、條件變量、信號量和令牌。互斥鎖和讀寫鎖:提供對臨界資源的保護,當多線程試圖訪問臨界資源時,都必須通過獲取鎖的方式來訪問臨界資源。(臨界資源:是被多線程共享的資源)當讀寫線程獲取鎖的頻率差別不大時,一般採用互斥鎖,如果讀線程訪問臨界資源的頻率大於寫線程,這個時候採用讀寫鎖較為合適,讀寫鎖允許多個讀線程同時訪問臨界資源,讀寫線程必須互斥訪問臨界資源。讀寫鎖的實現採用了互斥鎖,所以在讀寫次數差不多的情況下采用讀寫鎖性能沒有直接採用互斥鎖來的高。條件變量:提供線程之間的一種通知機制,當某一條件滿足時,線程A可以通知阻塞在條件變量上的線程B,B所期望的條件已經滿足,可以解除在條件變量上的阻塞操作,繼續做其他事情。信號量:提供對臨界資源的安全分配。如果存在多份臨界資源,在多個線程爭搶臨界資源的情況下,向線程提供安全分配臨界資源的方法。如果臨界資源的數量為1,將退化為鎖。令牌:一種高級的線程同步的方法。它既提供鎖的安全訪問臨界資源的功能,又利用了條件變量使得線程爭奪臨界資源時是有序的。下面提供Token在ACE中的一種實現方法。可以從下面的類圖,可以看到ACE是如何設計Token的。 ACE_Token:這個類是Token類,提供了獲取和釋放Token的方法。對於Token的獲取策略,ACE提供兩種實現:FIFO和LIFO。Token中對應著兩個隊列,一個是獲取Token是為了寫的隊列,另外一個是獲取Token是為了讀的隊列。ACE_Token_Queue:隊列是一個鏈表,該類提供對鏈表的管理操作。ACE_Token_Entry:是隊列中存放的元素,提供了對條件變量的封裝,一個元素代表一個線程試圖獲取Token。如果Token已經被獲取,線程需要阻塞在自己的Token上(隊列Entry中的條件變量上)。等待Token持有者釋放該Token,並通知阻塞的線程。 下面對ACE_Token中的組要方法提供分析。 獲取判斷是否有線程已經持有互斥鎖了,如果沒人持有,表示臨界資源是可用的,那麼可以立即返回成功。檢查是不是線程嘗試遞歸獲取互斥鎖。因為Token支持這種情況,所以也可立即返回成功。同時將nesting計數器自增。創建一個Token Entry,並將其排入隊列。調用用戶自定義的Hook方法,在線程進行sleep之前,用戶可以調用自定義的Hook方法。線程睡眠,如果線程喚醒後,發現當前線程不是Token的擁有者將繼續睡眠。線程被喚醒後,將Token entry從隊列中刪除。釋放如果發現嵌套層數大於0,需要將嵌套層數的計數器減一,然後讓該線程繼續持有Token。否則,該線程負責從隊列中按照一定的策略,取出Token entry,並通過該Entry通知阻塞在Entry上的線程,資源被釋放,你可以使用資源了。
線程同步是如何實現的?
線程的同步就相當於只有一個浴室(共用資源)。但是很多人要洗澡(線程),所以為了避免同一時間段有多人擁入浴室,在一個人進入浴室的時候把門鎖起來,這樣其他人只能等待,等那人洗好開了門才能進入下一個
實現的話就是給你線程中訪問共用資源的代碼段加上
public void run()
{
synchronized(Object)//括號內為監聽的共用資源對象名,注意是對象不是類
{
//改變共用資源的語句
}
}
C語言怎麼實現多線程同步
使用pthread庫執行多線程,這個是Linux下的線程庫 Windows下應該有自己的API,不過這種東西一般還是以Linux為標準。pthread_create()創建一個線程,傳入fun()的函數指針就行了。
然後這個Beep()的需求要進行線程間通信,可以用共享內存的方法,設一個bool變量flag共享,然後beep的時候設為false,beep完設成true。fun()裡面每次看一下這個flag,是false的話就不做動作等下一秒,基本可以滿足需求。
這樣做的好處是實現簡單,但時間是以1s為單位的。如果要8秒結束立刻執行,需要用條件變量的方法來控制,比較複雜,這樣的實現方式一個可以滿足需求了。
線程的同步與互斥是什麼.為什麼需要同步與互斥
線程同步是多個線程同時訪問同一資源,等待資源訪問結束,浪費時間,效率低 線程異步:訪問資源時在空閒等待時同時訪問其他資源,實現多線程機制 異步處理就是,你現在問我問題,我可以不回答你,等我用時間了再處理你這個問題.同步不就反之了,同步信息被立即處理 -- 直到信息處理完成才返回消息句柄;異步信息收到後將在後臺處理一段時間 -- 而早在信息處理結束前就返回消息句柄。
線程同步有幾種實現方法,都是什麼
繼承Thread 類與實現Runnable 接口都能實現多線程
synchronized,wait 與notify 可以實現同步
java中 synchronized同步處理後 為什麼只有一個線程在運行呢?
.修改了一下.,,這樣應該沒問題
class TextThread implements Runnable {
private int tickets=20;
public void run()
{
for(int i=0;i<=20;i++) 亥
go();
}
}
public synchronized void go() {
if(tickets>0) {
try {
Thread.sleep(100);
}
catch(Exception x) {}
System.out.println(Thread.currentThread().getName()+" 售出票 "+tickets--);
}
}
}
多線程程序設計中為什麼要使用線程同步策略
搜索一下Concurrent.Thread,它是一個允許進行多線程編程的庫。
其實都是使用settimeout之類的函數模擬出來的
例如:
settimeout(function1,1);
settimeout(function2,1);
settimeout(function3,1);
這樣就相當於同時觸發三個函數。如果這三個函數都是調用一段功能的代碼,那就相當於同時執行三次,也就是三個線程。
JS本身是不支持多線程的。
如何實現多線程的同步
多線程同步 "臨界區"(CriticalSection): 當把一段代碼放入一個臨界區, 線程執行到臨界區時就獨佔了, 讓其他也要執行此代碼的線程先等等; 使用格式如下:var CS: TRTLCriticalSection; {聲明一個 TRTLCriticalSection 結構類型變量; 它應該是全局的} InitializeCriticalSection(CS); {初始化} EnterCriticalSection(CS); {開始: 輪到我了其他線程走開} LeaveCriticalSection(CS); {結束: 其他線程可以來了} DeleteCriticalSection(CS); {刪除: 注意不能過早刪除} 多線程同步示例 1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls; 8 9 type 10 TForm1 = class(TForm) 11 ListBox1: TListBox; 12 Button1: TButton; 13 procedure FormCreate(Sender: TObject); 14 procedure FormDestroy(Sender: TObject); 15 procedure Button1Click(Sender: TObject); 16 end; 17 18 var 19 Form1: TForm1; 20 21 implementation 22 23 {$R *.dfm} 24 25 var 26 CS: TRTLCriticalSection; 27 28 function MyThreadFun(p: Pointer): DWORD; stdcall; 29 var 30 i: Integer; 31 begin 32 EnterCriticalSection(CS); 33 for i := 0 to 99 do Form1.ListBox1.Items.Add(IntToStr(i)); 34 LeaveCriticalSection(CS); 35 Result := 0; 36 end; 37 38 procedure TForm1.Button1Click(Sender: TObject); 39 var 40 ID: DWORD; 41 begin 42 CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); 43 CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); 44 CreateThread(nil, 0, @MyThreadFun, nil, 0, ID); 45 end; 46 47 procedure TForm1.FormCreate(Sender: TObject); 48 begin 49 ListBox1.Align := alLeft; 50 InitializeCriticalSection(CS); 51 end......