千家信息网

jdk中ReentrantLock类与Condition类结合的使用方法

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,本篇内容主要讲解"jdk中ReentrantLock类与Condition类结合的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"jdk中Reent
千家信息网最后更新 2026年11月02日jdk中ReentrantLock类与Condition类结合的使用方法

本篇内容主要讲解"jdk中ReentrantLock类与Condition类结合的使用方法",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"jdk中ReentrantLock类与Condition类结合的使用方法"吧!

我们在上一篇简单介绍了ReentrantLock类的基本使用,也就是获取锁,与释放锁。那如果我们要实现wait()和notify()等待通知的功能在ReentrantLock类中我们应该怎么办呢。这时我们就要借助一个新类了,它就是Condition类。Condition类也是JDK1.5以后新增的类。它可以实现多路通知功能,也就是说在一个Lock对象中可以创建多个Condition类相当于有多个锁对象,通知的时候可以选择性的进行线程通知,而不是notify()那样是由CPU随机决定通知的是哪个线程,Condition类使它在线程调度上更加灵活。下面我们看一下具体的事例。

/**
* 用户登录
*
* @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("线程结束\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
线程结束 thread: Thread-0

我们用ReentrantLock和Condition类成功实现了wait()和notify()暂停与通知的功能。使用还是比较简单,和以前的wait()、notify()方法使用基本一致。

condition.await(); // 相当于wait()方法
condition.signal();// 相当于notify()方法

我们知道用notifyAll()方法可以恢复暂停的所有线程,同样Condition类中也有同样的方法实现了该逻辑,只是方法不叫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线程结束\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线程结束\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线程结束 thread: Thread-0
await2线程结束 thread: Thread-1

我们看因为调用了signalAll()方法,所以所有暂停的线程都被恢复了。这和notifyAll()方法一样,没什么好说的。但如果我们想要实现恢复指定的线程那应该怎么办呢?我们知道调用notifyAll()方法恢复哪个线程是由CPU决定的,我们程序是控制不了的,这时有人可能会想到设置线程的优先级来实现让指定的线程优先执行。但这还不是绝对的。设置优先级也是说明那个线程获取执行的概率比较大,还是不能保证百分之百执行的。虽然用notifyAll()方法没有什么简单的办法让指定的线程恢复执行,但在Condition类中确可以很方便的实现此功能,这也是Condition类可以实现多路通知功能的体现。下面我们来演示一下用Condition类怎么实现我们上述的需求。

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线程结束\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线程结束\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线程结束 thread: Thread-0

我们看这时就实现了我们上述的需求。用Condition类可以唤醒我们指定的线程,确实比notify()更简单更方便。

到此,相信大家对"jdk中ReentrantLock类与Condition类结合的使用方法"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

线程 方法 倒计时 用户 功能 使用方法 登录 也就是 事例 优先级 内容 多个 对象 怎么办 是由 还是 需求 多路 学习 管理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技有限公司经营范围 河南真二互联网科技有限公司 互联网下的科技发展 互联网科技资迅 互联网科技小贷 以房互联网科技 壹账通互联网科技 互联网科技素材视频竖屏 安控科技rtu产品工业互联网 华夏互联网科技业 崇明区互联网教育科技售后服务 未来五年的互联网科技 互联网科技和法律行业 朱啸虎曾投资哪些互联网科技企业 用友工业互联网科技发展 无锡工业互联网科技有限公司 银行科技岗属于互联网吗 互联网科技快讯热点 杭州融税互联网科技有限公司 恒生科技互联网指数十大成分股 云信互联网科技有限公司 互联网科技logo设计 郑州华宇互联网科技 四个字互联网科技公司取名 顺网科技2021年互联网排名 互联网科技公司招聘 广州恒生互联网科技有限 厦门比较好的科技互联网公司 互联网科技产业特征 工业互联网科技创业
0