多執行緒學習筆記(六)之鎖物件Lock

2021-07-31 15:27:33 字數 3561 閱讀 6345

首先我們回顧下同步**塊,例如:

object obj = new

object();

void show()

}

同步**塊對鎖的操作是隱式的,執行完同步**塊中的內容,自動釋放鎖。而lock將鎖封裝成為了物件,即把對鎖操作的隱式操作換成了顯示操作。可以將如上**改寫:

lock

lock = new reentrantlock();

void show()

jdk1.5之後將同步和鎖封裝成了物件,並將操作鎖的隱式方式定義到了該物件中,將隱式動作變成了顯示動作。

上述**中存在隱患,例如code部門產生異常throw exception的話,會導致後面**無法執行,即沒有釋放鎖,因此需要將釋放鎖的操作放在finally塊中。

lock lock = new reentrantlock();

void show()finally

}

condition newcondition():返回繫結到此lock例項的新condition例項

public inte***ce condition ,condition將object監視器方法(wait,notify和notifyall)分解成截然不同的物件,以便通過將這些物件與任意lock實現組合使用,為每個物件提供多個等待set(wait-set)。其中,lock替代了synchronized方法和語句的使用,condition替代了object監視器方法的使用。

條件(也稱為條件佇列或條件變數)為執行緒提供乙個含義,以便在某個狀態條件現在可能為true的另乙個執行緒通知它之前,一直掛起該執行緒(即讓其「等待」)。因為訪問此共享狀態資訊發生在不同的執行緒中,所以它必須受保護,因此要將某種形式的鎖與該條件相關聯。等待提供乙個條件的主要屬性是:以原子方式釋放相關的鎖,並掛起當前執行緒,就像object.wait做的那樣。

condition例項實質上被繫結到乙個鎖上。要為特定lock例項獲得condition例項,請使用其newcondition()方法。

具體是什麼意思呢,個人用自己的理解白話解釋下:

正常的傳統synchronized塊方式,每個鎖物件obj對應有一套*wait,notify,notifyall方法(因為不同鎖物件的wait和notify是不起作用的),而condition對wait,notify,notifyall方法進行了封裝,多個condition物件可以同時所屬於同乙個lock鎖物件*

傳統方式:

class

object

class

demo

extends

object

demo d = new demo();

synchronized(d)

condition方式:

inte***ce condition

lock lock = new reentrantlock();

condition c1 = lock.newcondition();//根據鎖物件lock獲取一組監視器物件

condition c2 = lock.newcondition();//第二組監視器

由上可以發現lock的目的是為了替代同步,condition的目的是為了替代object中的方法

class

resourcedemocatch (interruptedexception e)

}this.name = name + count;

count++;

system.out.println(thread.currentthread().getname()+"...生產者..."+this.name);

flag = true;

//notifyall();

con.signalall();

}finally

}//消費者

public

void out()catch (interruptedexception e)

}system.out.println(thread.currentthread().getname()+"......消費者......"+this.name);

flag = false;

//notifyall();

con.signalall();

}finally

}}//生產者

class

producer

implements

runnable

public

void run()

}}//消費者

class

consumer

implements

runnable

public

void run()

}}public

class

producerconsumerdemo

}

注意點:

具體原因解釋可以參見之前部落格:

使用兩個監視器,一組監視生產者,一組監視消費者,而之前的傳統方法要想實現,需要兩個鎖,因為傳統方式一把鎖上只有一組監視器,而lock的方式,一把鎖上可以繫結多組監視器。因此可以實現「喚醒對方執行緒」,解決了之前傳統方法notifyall方式的效率低的問題。

class resourcedemocatch (interruptedexception e) 

}this.name = name + count;

count++;

system.out.println(thread.currentthread().getname()+"...生產者..."+this.name);

flag = true;

//notifyall();

consumer_con.signalall();

}finally

}//消費者

public

void

out()catch (interruptedexception e)

}system.out.println(thread.currentthread().getname()+"......消費者......"+this.name);

flag = false;

//notifyall();

producer_con.signalall();

}finally

}}//生產者

class producer implements runnable

public

void

run()

}}//消費者

class consumer implements runnable

public

void

run()

}}public

class producerconsumerdemo

}

Python學習筆記 多執行緒鎖

多執行緒的鎖 如果有多個執行緒同時操作乙個物件,如果沒有很好地保護該物件,會造成程式結果的不可預期 多執行緒中,所有變數都由所有執行緒共享,所以,任何乙個變數都可以被任何乙個執行緒修改,因此,執行緒之間共享資料最大的危險在於多個執行緒同時改乙個變數,把內容給改亂了。因此需要用鎖threading.l...

多執行緒程式設計學習筆記(六)

多執行緒程式設計學習筆記 六 執行緒區域性儲存 tls 存放區域性儲存步驟 1 申請資料槽 localdatastoreslot slot thread.getnameddataslot para 如果不存在名為para的資料槽,將分配乙個所有執行緒均可用的para資料槽 2 往資料槽存放資料 my...

C 多執行緒學習 六 互斥物件

如何控制好多個執行緒相互之間的聯絡,不產生衝突和重複,這需要用到互斥物件,即 system.threading 命名空間中的 mutex 類。我們可以把mutex看作乙個計程車,乘客看作執行緒。乘客首先等車,然後上車,最後下車。當乙個乘客在車上時,其他乘客就只有等他下車以後才可以上車。而執行緒與mu...