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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

釋義

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

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();

}

}

}

整個(gè)過程沒有發(fā)生死鎖的情況,截取一部分輸出結(jié)果如下:

Thread-8492

Thread-8492

Thread-8494

Thread-8494

Thread-8495

Thread-8495

Thread-8493

Thread-8493

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

不可重入鎖

不可重入鎖,與可重入鎖相反,不可遞歸調(diào)用,遞歸調(diào)用就發(fā)生死鎖??吹揭粋€(gè)經(jīng)典的講解,使用自旋鎖來模擬一個(gè)不可重入鎖,代碼如下:

import java.util.concurrent.atomic.AtomicReference;

public class UnreentrantLock {

private AtomicReference owner = new AtomicReference();

public void lock() {

Thread current = Thread.currentThread();

//這句是很經(jīng)典的“自旋”語法,AtomicInteger中也有

for (;;) {

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

return;

}

}

}

public void unlock() {

Thread current = Thread.currentThread();

owner.compareAndSet(current, null);

}

}

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

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;

}

//這句是很經(jīng)典的“自旋”式語法,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);

}

}

}

}

在執(zhí)行每次操作之前,判斷當(dāng)前鎖持有者是否是當(dāng)前對象,采用state計(jì)數(shù),不用每次去釋放鎖。

ReentrantLock中可重入鎖實(shí)現(xiàn)

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

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中維護(hù)了一個(gè)private volatile int state來計(jì)數(shù)重入次數(shù),避免了頻繁的持有釋放操作,這樣既提升了效率,又避免了死鎖。

超強(qiáng)干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。