Java多线程--13 Condition


        Condition将Object监视器方法(wait、notify和notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set(wait-set)。其中,Lock替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用。

        Condition(也称为条件队列或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为true的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式释放相关的锁,并挂起当前线程,就像Object.wait做的那样。   

  Condition 实例实质上被绑定到一个锁上。要为特定 Lock 实例获得 Condition 实例,请使用其 newCondition() 方法。 


ConditionObject
void await() 

造成当前线程在接到信号或被中断之前一直处于等待状态。

void wait() 

在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。

boolean await(long time, TimeUnit unit) 

造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。

void wait(long timeout) 

在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。

void signal() 

唤醒一个等待线程。

void notify() 

唤醒在此对象监视器上等待的单个线程

void signalAll() 

唤醒所有等待线程。

void notifyAll() 

唤醒在此对象监视器上等待的所有线程。


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionDemo {

	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	
	public void method1(){
		try {
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态,并释放锁..");
			condition.await();	//await释放锁     Object wait
			System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void method2(){
		try {
			lock.lock();
			System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method2..");
			Thread.sleep(3000);
			System.out.println("当前线程:" + Thread.currentThread().getName() + " 唤醒t1线程 ..");
			condition.signal();	//唤醒一个等待线程  Object notify
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public static void main(String[] args) {
		
		final ConditionDemo uc = new ConditionDemo();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {	uc.method1(); }
		}, "t1");
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {	uc.method2(); }
		}, "t2");
		t1.start();

		t2.start();
	}	
}

当前线程:t1进入method1..

当前线程:t1进入等待状态,并释放锁..

当前线程:t2进入method2..

当前线程:t2 唤醒t1线程 ..

当前线程:t1继续执行...




多个Condition

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ManyCondition {

	private ReentrantLock lock = new ReentrantLock();
	private Condition c1 = lock.newCondition();
	private Condition c2 = lock.newCondition();
	
	public void m1(){
		try {
			lock.lock();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m1等待..");
			c1.await();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m1继续..");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void m2(){
		try {
			lock.lock();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m2等待..");
			c1.await();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m2继续..");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void m3(){
		try {
			lock.lock();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "进入方法m3等待..");
			c2.await();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "方法m3继续..");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void m4(){
		try {
			lock.lock();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
			c1.signalAll();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void m5(){
		try {
			lock.lock();
			System.out.println("当前线程:" +Thread.currentThread().getName() + "唤醒..");
			c2.signal();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public static void main(String[] args) throws Exception {
		ManyCondition umc = new ManyCondition();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {	umc.m1();}
		},"t1");
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {	umc.m2();}
		},"t2");
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {	umc.m3();}
		},"t3");
		Thread t4 = new Thread(new Runnable() {
			@Override
			public void run() {	umc.m4();}
		},"t4");
		Thread t5 = new Thread(new Runnable() {
			@Override
			public void run() {	umc.m5();}
		},"t5");
		
		t1.start();	// c1
		t2.start();	// c1
		t3.start();	// c2
		
		Thread.sleep(2000);
		t4.start(); // c1
		
		Thread.sleep(2000);
		t5.start(); // c2
	}
}

当前线程:t1进入方法m1等待..

当前线程:t2进入方法m2等待..

当前线程:t3进入方法m3等待..

当前线程:t4唤醒..

当前线程:t1方法m1继续..

当前线程:t2方法m2继续..

当前线程:t5唤醒..

当前线程:t3方法m3继续..




多线程 Condition

2020.11.18 00:22

https://www.meihaocloud.com.com/319.html , 欢迎转载,请在文章页标出原文连接 !


Copyright © 2020 千夕网 联系站长

粤公网安备 44030302001408号 粤ICP备19099833号-1