java多執行緒-JUC-Look鎖了誰?
阿新 • • 發佈:2018-11-08
java多執行緒-JUC-Look到底鎖了誰?
demo
// 程式碼
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/***
* ReentrantLock 鎖的是 自己內部維護 的 資源 : state
* 所有執行緒 爭奪的 是 ReentrantLock 內部的 state 屬性的佔有權
* */
public class TestReentrantLock extends Thread {
private static DB db = new DB();
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
db.add();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
db.buy();
db.buy();
}
}).start();
//db.buyNoLook();
}
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
new TestReentrantLock().start();
}
}
}
//程式碼鎖,非資料庫鎖
class DB {
private Lock lock = new ReentrantLock();
private Lock lock_add = new ReentrantLock();
// 用static表示該鎖是該物件例項共享的
int i = 100;
// 用static表示該變數是物件例項共享的
//加鎖 減庫存
public void buy() {
lock.lock();
try{
System.out.println("購買:"+(--i));
} finally {
lock.unlock();
}
}
/**
* 功能描述:
* 必須是同一個 look 鎖,才能對 i 有鎖住效果
* look 可以用在不同的方法塊中
* lock_add 和 look 的使用,相互沒有影響
* TODO
* @CreateTime [2018/10/22 0022 11:18]
* @Param
*/
public void add() {
lock.lock();
//lock_add.lock();
try{
System.out.println("進貨:"+(++i));
} finally {
lock.unlock();
// lock_add.unlock();
}
}
//無所 減庫存
public void buyNoLook() {
i--;
System.out.println(i);
}
}
總結
- 例項中 class DB 代表資料庫
- 多個執行緒同時 去 增加庫存 和 減少庫存.用 look 去鎖;
- 必須只能使用 look 一個鎖例項;如果 用 lock_add 和 look混搭使用,無效果;
- 可以看出 所有執行緒去呼叫 look.look()方法時,會產生同步制約(內部是自旋)效果;實質上是所有執行緒執行到 look.look()方法是,都會去獲得 state值;