多執行緒-執行緒同步有幾種實現方式
執行緒同步有幾種實現方式
1. Synchronized
在方法級別 public synchronized ….
在程式碼塊 synchronized(物件){}
1. 當synchronized作用在方法上的時候,鎖住的就是這個物件的例項 synchronized(this)
2. 當synchronized作用在靜態方法上的時候,鎖住的是這個物件的Class例項,因為class資料儲存在永久區,所以靜態方法鎖相當於全域性鎖
3. 當synchronized作用在某一個物件例項上的時候,鎖住的是對應的程式碼塊
a) 執行規則
1. 當兩個併發執行緒訪問同一個物件中的synchronized(obj) 同步塊,只能有一個執行緒得到執行,另外一個執行緒必須等待前一個執行緒執行完畢
2. 當一個執行緒訪問synchronized(this) 同步塊時, 另一個執行緒仍然可以訪問當前物件內的非synchroinzed(this)同步塊程式碼
3. 如果一個執行緒訪問當前物件中的一個synchroinzed(this)同步塊,其他執行緒中對當前物件中其他的synchroinzed同步塊程式碼訪問將被阻塞
4. 同步是一個耗效能的操作,因此我們儘量減少同步的內容,最好不要載入整個方法上
2. Lock
Jdk5以後, 增加了一個java.util.concurrent包
通過Lock來實現多執行緒的同步鎖,好處是非常靈活。
ReentrantLock 會由最近成功獲得鎖定並且還沒有釋放該鎖的執行緒擁有。當鎖沒有被另一個執行緒擁有時,呼叫
如果當前執行緒已經擁有了該鎖,則會立即返回
公平機制,提供了一個可選的公平鎖引數。
常用方法:
lock() 如果被其他執行緒鎖定,則會等待鎖釋放
tryLock() 返回boolean值, 如果已經被lock,則會返回false,且不會等待
lock和synchroinzed
1. 實現層面, synchronized由jvm實現, lock jdk實現
如何控制多個執行緒的執行順序
Join
通過join去控制執行緒的執行順序
Wait() /notify()/notifyAll()
CountDownLatch/CyclicBarrier/Semaphore
CountDownLatch 等待n個執行緒執行完以後才能執行
CyclicBarrier
Semaphore