Java并发多线程编程——Condition接口的理解及使用
Posted 小志的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发多线程编程——Condition接口的理解及使用相关的知识,希望对你有一定的参考价值。
目录
一、Condition接口的理解
- Condition是个接口,基本的方法就是await()和signal()方法;
- Condition用来替代传统的Object的wait()、notify()实现线程间的协作。相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效;
- Condition对象是依赖于lock对象的,也就是说condition对象需要通过lock对象进行创建出来; 调用Condition的await()和signal()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用。
二、Condition接口结构及常用方法
- await() :造成当前线程在接到信号或被中断之前一直处于等待状态。
- awaitUninterruptibly() :造成当前线程在接到信号之前一直处于等待状态。【注意:该方法对中断不敏感】。
- awaitNanos(long nanosTimeout) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。返回值表示剩余时间,如果在nanosTimesout之前唤醒,那么返回值 = nanosTimeout - 消耗时间,如果返回值 <= 0 ,则可以认定它已经超时了。
- await(long time, TimeUnit unit) :造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。
- awaitUntil(Date deadline) :造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。如果没有到指定时间就被通知,则返回true,否则表示到了指定时间,返回返回false。
- signal() :唤醒一个等待线程。该线程从等待方法返回前必须获得与Condition相关的锁。
- signal()All :唤醒所有等待线程。能够从等待方法返回的线程必须获得与Condition相关的锁。
三、使用Object类中的wait()、notifyAll()实现多个线程按顺序执行示例
1、案例场景
多个线程,按照线程顺序依次循环执行。
2、代码
package com.xz.thread.t15;
/**
* @description: 创建a线程类
* @author: xz
* @create: 2021-05-24 21:08
*/
public class Atarget implements Runnable{
private Demo demo;
public Atarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.a();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t15;
/**
* @description: 创建b线程类
* @author: xz
* @create: 2021-05-24 21:14
*/
public class Btarget implements Runnable{
private Demo demo;
public Btarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.b();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t15;
/**
* @description: 创建c线程类
* @author: xz
* @create: 2021-05-24 21:16
*/
public class Ctarget implements Runnable{
private Demo demo;
public Ctarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.c();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t15;
/**
* @description:
* @author: xz
* @create: 2021-05-23 22:12
*/
public class Demo {
private int signal;
public synchronized void a(){
while (signal != 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【a】线程执行");
signal++;
notifyAll();
}
public synchronized void b(){
while (signal != 1){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【b】线程执行");
signal++;
notifyAll();
}
public synchronized void c(){
while (signal != 2){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【c】线程执行");
signal =0;
notifyAll();
}
public static void main(String[] args) {
Demo d =new Demo();
Atarget a = new Atarget(d);
Btarget b = new Btarget(d);
Ctarget c = new Ctarget(d);
new Thread(a).start();
new Thread(b).start();
new Thread(c).start();
}
}
2、运行main函数,输出结果如下:
四、使用Condition接口中的await()、signal()现多个线程按顺序执行示例
1、案例场景
多个线程,按照线程顺序依次循环执行。
2、代码
package com.xz.thread.t16;
/**
* @description: 创建a线程类
* @author: xz
* @create: 2021-05-24 21:08
*/
public class Atarget implements Runnable{
private Demo demo;
public Atarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.a();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t16;
/**
* @description: 创建b线程类
* @author: xz
* @create: 2021-05-24 21:14
*/
public class Btarget implements Runnable{
private Demo demo;
public Btarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.b();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t16;
/**
* @description: 创建c线程类
* @author: xz
* @create: 2021-05-24 21:16
*/
public class Ctarget implements Runnable{
private Demo demo;
public Ctarget(Demo demo){
this.demo =demo;
}
@Override
public void run() {
while(true){
demo.c();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.xz.thread.t16;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @description:
* @author: xz
* @create: 2021-05-23 22:32
*/
public class Demo {
private int signal;
Lock lock = new ReentrantLock();
Condition a = lock.newCondition();
Condition b = lock.newCondition();
Condition c = lock.newCondition();
public void a(){
lock.lock();
while (signal != 0){
try {
a.await();//线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【a】方法执行");
signal++;
b.signal();//唤醒b方法
lock.unlock();
}
public void b(){
lock.lock();
while (signal != 1){
try {
b.await();//线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【b】方法执行");
signal++;
c.signal();//唤醒c方法
lock.unlock();
}
public void c(){
lock.lock();
while (signal != 2){
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("【c】方法执行");
signal =0;
a.signal();//唤醒a方法
lock.unlock();
}
public static void main(String[] args) {
Demo d =new Demo();
Atarget a = new Atarget(d);
Btarget b = new Btarget(d);
Ctarget c = new Ctarget(d);
new Thread(a).start();
new Thread(b).start();
new Thread(c).start();
}
}
2、运行main函数,输出结果如下:
以上是关于Java并发多线程编程——Condition接口的理解及使用的主要内容,如果未能解决你的问题,请参考以下文章
Java——多线程高并发系列之Condition接口中的await()signal()signAll()方法
Java——多线程高并发系列之Condition接口中的await()signal()signAll()方法
JAVA并发编程实战12使用condition实现多线程下的有界缓存先进先出队列
Java多线程与并发编程——ConditionCallable&Future