Java使用Condition实现精准唤醒线程详解
Condition简要介绍
Condition是一个接口,创建Condition的实例不能直接new,Java为我们提供一个通过Lock类实例来调用newCondition()的方法来创建。Condition因素出Object监视器方法( wait , notify和notifyAll )到不同的对象,以得到具有多个等待集的每个对象,通过将它们与使用任意的组合的效果Lock个实现。 如果Lock替换了synchronized方法和语句的使用,则Condition将替换Object监视方法的使用。
条件(也称为条件队列或条件变量 )为一个线程提供暂停执行(“等待”)的手段,直到另一个线程通知某个状态条件现在可能为真。 由于对此共享状态信息的访问发生在不同的线程中,因此必须对其进行保护,因此某种形式的锁定与该条件相关联。 等待条件提供的关键属性是它以原子方式释放关联的锁并挂起当前线程,就像Object.wait一样。
Condition里的主要方法
使用Condition的Demo
例子1
package testJUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestCondition {
public static void main(String[] args) {
Product3 product = new Product3();
new Thread(()->{
for (int i = 0; i < 5; i++)
new Producer(product).getProduct();
},"工厂").start();
new Thread(()->{
for (int i = 0; i < 5; i++)
new Consumer(product).saleProduct();
},"学生").start();
}
}
class Product3 {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private int flag = 1;//标识符
public void getProduct() {
//加锁
lock.lock();
try {
//使用while循环,可以有效避免线程虚假唤醒
while (flag != 1) {
condition1.await();
}
flag = 2;
//唤醒saleProduct
condition2.signal();
System.out.println(Thread.currentThread().getName() + "生产一个产品");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解锁
lock.unlock();
}
}
public void saleProduct() {
lock.lock();
try {
while (flag != 2) {
condition2.await();
}
flag = 1;
//唤醒getProduct
condition1.signal();
System.out.println(Thread.currentThread().getName()+"消费了一个产品");
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
//实体类
class Producer{
private Product3 product = null;
public Producer(Product3 product) {
this.product = product;
}
public void getProduct(){
product.getProduct();
}
}
class Consumer{
private Product3 product = null;
public Consumer(Product3 product) {
this.product = product;
}
public void saleProduct(){
product.saleProduct();
}
}
结果
例子2
package testJUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestCondition {
public static void main(String[] args) {
Print print = new Print();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printA();
}).start();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printB();
}).start();
new Thread(() -> {
for (int i = 0; i < 5; i++)
print.printC();
}).start();
}
}
class Print {
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
private int number = 1;
//输出A的方法
public void printA() {
//加锁
lock.lock();
try {
//使用while循环,可以有效避免线程虚假唤醒
while (number != 1) {
condition1.await();
}
number = 2;
//唤醒输出B的方法
condition2.signal();
System.out.println("AAA");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解锁
lock.unlock();
}
}
//输出B的方法
public void printB() {
//加锁
lock.lock();
try {
while (number != 2) {
condition2.await();
}
System.out.println("BBB");
number = 3;
//唤醒C
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//唤醒输出C的方法
lock.unlock();
}
}
//输出C的方法
public void printC() {
//加锁
lock.lock();
try {
while (number != 3) {
condition3.await();
}
System.out.println("CCC");
number = 1;
//唤醒输出A的方法
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//解锁
lock.unlock();
}
}
}
结果2
到此这篇关于Java使用Condition实现精准唤醒线程详解的文章就介绍到这了,更多相关Java Condition精准唤醒线程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341