日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java重入锁_java并发编程:可重入锁是什么?

發布時間:2024/4/11 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java重入锁_java并发编程:可重入锁是什么? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

釋義

廣義上的可重入鎖指的是可重復可遞歸調用的鎖,在外層使用鎖之后,在內層仍然可以使用,并且不發生死鎖(前提得是同一個對象或者class),這樣的鎖就叫做可重入鎖。ReentrantLock和synchronized都是可重入鎖,下面是一個用synchronized實現的例子:

public class ReentrantTest implements Runnable {

public synchronized void get() {

System.out.println(Thread.currentThread().getName());

set();

}

public synchronized void set() {

System.out.println(Thread.currentThread().getName());

}

public void run() {

get();

}

public static void main(String[] args) {

ReentrantTest rt = new ReentrantTest();

for(;;){

new Thread(rt).start();

}

}

}

整個過程沒有發生死鎖的情況,截取一部分輸出結果如下:

Thread-8492

Thread-8492

Thread-8494

Thread-8494

Thread-8495

Thread-8495

Thread-8493

Thread-8493

set()和get()同時輸出了線程名稱,表明即使遞歸使用synchronized也沒有發生死鎖,證明其是可重入的。

不可重入鎖

不可重入鎖,與可重入鎖相反,不可遞歸調用,遞歸調用就發生死鎖。看到一個經典的講解,使用自旋鎖來模擬一個不可重入鎖,代碼如下:

import java.util.concurrent.atomic.AtomicReference;

public class UnreentrantLock {

private AtomicReference owner = new AtomicReference();

public void lock() {

Thread current = Thread.currentThread();

//這句是很經典的“自旋”語法,AtomicInteger中也有

for (;;) {

if (!owner.compareAndSet(null, current)) {

return;

}

}

}

public void unlock() {

Thread current = Thread.currentThread();

owner.compareAndSet(current, null);

}

}

代碼也比較簡單,使用原子引用來存放線程,同一線程兩次調用lock()方法,如果不執行unlock()釋放鎖的話,第二次調用自旋的時候就會產生死鎖,這個鎖就不是可重入的,而實際上同一個線程不必每次都去釋放鎖再來獲取鎖,這樣的調度切換是很耗資源的。稍微改一下,把它變成一個可重入鎖:

import java.util.concurrent.atomic.AtomicReference;

public class UnreentrantLock {

private AtomicReference owner = new AtomicReference();

private int state = 0;

public void lock() {

Thread current = Thread.currentThread();

if (current == owner.get()) {

state++;

return;

}

//這句是很經典的“自旋”式語法,AtomicInteger中也有

for (;;) {

if (!owner.compareAndSet(null, current)) {

return;

}

}

}

public void unlock() {

Thread current = Thread.currentThread();

if (current == owner.get()) {

if (state != 0) {

state--;

} else {

owner.compareAndSet(current, null);

}

}

}

}

在執行每次操作之前,判斷當前鎖持有者是否是當前對象,采用state計數,不用每次去釋放鎖。

ReentrantLock中可重入鎖實現

這里看非公平鎖的鎖獲取方法:

final boolean nonfairTryAcquire(int acquires) {

final Thread current = Thread.currentThread();

int c = getState();

if (c == 0) {

if (compareAndSetState(0, acquires)) {

setExclusiveOwnerThread(current);

return true;

}

}

//就是這里

else if (current == getExclusiveOwnerThread()) {

int nextc = c + acquires;

if (nextc < 0) // overflow

throw new Error("Maximum lock count exceeded");

setState(nextc);

return true;

}

return false;

}

在AQS中維護了一個private volatile int state來計數重入次數,避免了頻繁的持有釋放操作,這樣既提升了效率,又避免了死鎖。

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的java重入锁_java并发编程:可重入锁是什么?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。