本篇內(nèi)容主要講解“jdk中ReentrantLock類與Condition類結(jié)合的使用方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“jdk中ReentrantLock類與Condition類結(jié)合的使用方法”吧!
創(chuàng)新互聯(lián)始終致力于在企業(yè)網(wǎng)站建設(shè)領(lǐng)域發(fā)展。秉承“創(chuàng)新、求實、誠信、拼搏”的企業(yè)精神,致力為企業(yè)提供全面的網(wǎng)絡(luò)宣傳與技術(shù)應(yīng)用整體策劃方案,為企業(yè)提供包括“網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站建設(shè)、手機網(wǎng)站建設(shè)、微信網(wǎng)站建設(shè)、小程序定制開發(fā)、購物商城網(wǎng)站建設(shè)、平臺網(wǎng)站建設(shè)秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
我們在上一篇簡單介紹了ReentrantLock類的基本使用,也就是獲取鎖,與釋放鎖。那如果我們要實現(xiàn)wait()和notify()等待通知的功能在ReentrantLock類中我們應(yīng)該怎么辦呢。這時我們就要借助一個新類了,它就是Condition類。Condition類也是JDK1.5以后新增的類。它可以實現(xiàn)多路通知功能,也就是說在一個Lock對象中可以創(chuàng)建多個Condition類相當于有多個鎖對象,通知的時候可以選擇性的進行線程通知,而不是notify()那樣是由CPU隨機決定通知的是哪個線程,Condition類使它在線程調(diào)度上更加靈活。下面我們看一下具體的事例。
/**
* 用戶登錄
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void await() {
try {
lock.lock();
System.out.println(String.format("線程開始\tthread: %s", Thread.currentThread().getName()));
condition.await();
System.out.println(String.format("線程結(jié)束\tthread: %s", Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signal() {
lock.lock();
System.out.println(String.format("線程恢復\tthread: %s", Thread.currentThread().getName()));
condition.signal();
lock.unlock();
}
}
/**
* 管理用戶請求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestAdmin extends Thread {
private Userinfo userinfo;
public RequestAdmin(Userinfo userinfo) {
this.userinfo = userinfo;
}
@Override
public void run() {
userinfo.await();
}
}
/**
* 用戶請求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestUser extends Thread {
private Userinfo userinfo;
public RequestUser(Userinfo userinfo) {
this.userinfo = userinfo;
}
@Override
public void run() {
userinfo.signal();
}
}
/**
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-20 13:35
* @since 1.0.0
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Userinfo userinfo = new Userinfo();
RequestAdmin requestAdmin = new RequestAdmin(userinfo);
RequestUser requestUser = new RequestUser(userinfo);
requestAdmin.start();
Thread.sleep(1000);
for (int i = 3; i > 0; i--) {
System.out.println(String.format("倒計時:%s", i));
Thread.sleep(1000);
}
requestUser.start();
}
}
線程開始 thread: Thread-0
倒計時:3
倒計時:2
倒計時:1
線程恢復 thread: Thread-1
線程結(jié)束 thread: Thread-0
我們用ReentrantLock和Condition類成功實現(xiàn)了wait()和notify()暫停與通知的功能。使用還是比較簡單,和以前的wait()、notify()方法使用基本一致。
condition.await(); // 相當于wait()方法
condition.signal();// 相當于notify()方法
我們知道用notifyAll()方法可以恢復暫停的所有線程,同樣Condition類中也有同樣的方法實現(xiàn)了該邏輯,只是方法不叫notifyAll()而是叫signalAll()方法。請看下面事例。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 用戶登錄
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void await1() {
try {
lock.lock();
System.out.println(String.format("await1線程開始\tthread: %s", Thread.currentThread().getName()));
condition.await();
System.out.println(String.format("await1線程結(jié)束\tthread: %s", Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void await2() {
try {
lock.lock();
System.out.println(String.format("await2線程開始\tthread: %s", Thread.currentThread().getName()));
condition.await();
System.out.println(String.format("await2線程結(jié)束\tthread: %s", Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signalAll() {
lock.lock();
System.out.println(String.format("恢復所有線程\tthread: %s", Thread.currentThread().getName()));
condition.signalAll();
lock.unlock();
}
}
/**
* 管理用戶請求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestAdmin extends Thread {
private Userinfo userinfo;
public RequestAdmin(Userinfo userinfo) {
this.userinfo = userinfo;
}
@Override
public void run() {
userinfo.await1();
}
}
/**
* 用戶請求
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:44
* @since 1.0.0
*/
public class RequestUser extends Thread {
private Userinfo userinfo;
public RequestUser(Userinfo userinfo) {
this.userinfo = userinfo;
}
@Override
public void run() {
userinfo.await2();
}
}
/**
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-20 13:35
* @since 1.0.0
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Userinfo userinfo = new Userinfo();
RequestAdmin requestAdmin = new RequestAdmin(userinfo);
RequestUser requestUser = new RequestUser(userinfo);
requestAdmin.start();
requestUser.start();
Thread.sleep(1000);
for (int i = 3; i > 0; i--) {
System.out.println(String.format("倒計時:%s", i));
Thread.sleep(1000);
}
userinfo.signalAll();
}
}
await1線程開始 thread: Thread-0
await2線程開始 thread: Thread-1
倒計時:3
倒計時:2
倒計時:1
恢復所有線程 thread: main
await1線程結(jié)束 thread: Thread-0
await2線程結(jié)束 thread: Thread-1
我們看因為調(diào)用了signalAll()方法,所以所有暫停的線程都被恢復了。這和notifyAll()方法一樣,沒什么好說的。但如果我們想要實現(xiàn)恢復指定的線程那應(yīng)該怎么辦呢?我們知道調(diào)用notifyAll()方法恢復哪個線程是由CPU決定的,我們程序是控制不了的,這時有人可能會想到設(shè)置線程的優(yōu)先級來實現(xiàn)讓指定的線程優(yōu)先執(zhí)行。但這還不是絕對的。設(shè)置優(yōu)先級也是說明那個線程獲取執(zhí)行的概率比較大,還是不能保證百分之百執(zhí)行的。雖然用notifyAll()方法沒有什么簡單的辦法讓指定的線程恢復執(zhí)行,但在Condition類中確可以很方便的實現(xiàn)此功能,這也是Condition類可以實現(xiàn)多路通知功能的體現(xiàn)。下面我們來演示一下用Condition類怎么實現(xiàn)我們上述的需求。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 用戶登錄
*
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-15 10:35
* @since 1.0.0
*/
public class Userinfo {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
public void await1() {
try {
lock.lock();
System.out.println(String.format("await1線程開始\tthread: %s", Thread.currentThread().getName()));
condition1.await();
System.out.println(String.format("await1線程結(jié)束\tthread: %s", Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void await2() {
try {
lock.lock();
System.out.println(String.format("await2線程開始\tthread: %s", Thread.currentThread().getName()));
condition2.await();
System.out.println(String.format("await2線程結(jié)束\tthread: %s", Thread.currentThread().getName()));
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void signalAll1() {
lock.lock();
System.out.println(String.format("恢復所有線程\tthread: %s", Thread.currentThread().getName()));
condition1.signalAll();
lock.unlock();
}
public void signalAll2() {
lock.lock();
System.out.println(String.format("恢復所有線程\tthread: %s", Thread.currentThread().getName()));
condition2.signalAll();
lock.unlock();
}
}
/**
* @author Sama
* @author admin@jilinwula.com
* @date 2017-03-20 13:35
* @since 1.0.0
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
Userinfo userinfo = new Userinfo();
RequestAdmin requestAdmin = new RequestAdmin(userinfo);
RequestUser requestUser = new RequestUser(userinfo);
requestAdmin.start();
requestUser.start();
Thread.sleep(1000);
for (int i = 3; i > 0; i--) {
System.out.println(String.format("倒計時:%s", i));
Thread.sleep(1000);
}
userinfo.signalAll1();
}
}
await1線程開始 thread: Thread-0
await2線程開始 thread: Thread-1
倒計時:3
倒計時:2
倒計時:1
恢復所有線程 thread: main
await1線程結(jié)束 thread: Thread-0
我們看這時就實現(xiàn)了我們上述的需求。用Condition類可以喚醒我們指定的線程,確實比notify()更簡單更方便。
到此,相信大家對“jdk中ReentrantLock類與Condition類結(jié)合的使用方法”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
當前文章:jdk中ReentrantLock類與Condition類結(jié)合的使用方法
網(wǎng)頁鏈接:http://chinadenli.net/article40/gogeho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、App設(shè)計、品牌網(wǎng)站設(shè)計、靜態(tài)網(wǎng)站、響應(yīng)式網(wǎng)站、網(wǎng)站策劃
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)