Condition定义了等待(await)/通知(signal)两种类型的方法,当前线程调用这些方法时,需要提前获取到Condition对象关联的锁。Condition对象是由Lock对象(调用Lock对象的newCondition()方法)创建出来的,换句话说,Condition是依赖Lock对象的。
一般都会将Condition对象作为成员变量。当调用await()方法后,当前线程会释放锁并在此等待,而其他线程调用Condition对象的signal()方法,通知当前线程后,当前线程才从await()方法返回,并且在返回前已经获取了锁。
两个线程轮流打印A、B,代码如下:
package thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class TestCondition { private ReentrantLock lock=new ReentrantLock(); Condition conditionA=lock.newCondition(); Condition conditionB=lock.newCondition(); public static void main(String[] args) { TestCondition test=new TestCondition(); test.new OutPutA().start(); test.new OutPutB().start(); } class OutPutA extends Thread{ public void run(){ while(true){ try { lock.lock(); System.out.print("A"); conditionB.signal(); conditionA.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } } } class OutPutB extends Thread{ public void run(){ while(true){ try { lock.lock(); System.out.println("_B"); conditionA.signal(); conditionB.await(); } catch (InterruptedException e) { e.printStackTrace(); }finally{ lock.unlock(); } } } } }
两个线程轮流打印A、B,另外一种代码如下:
package threadPrint; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class PrintAB implements Runnable{ private Lock lock=new ReentrantLock(); private Condition thisCondition=lock.newCondition(); private Condition nextCondition=lock.newCondition(); private Character character; private static int count=10; public PrintAB(Lock lock,Condition thisCondition,Condition nextCondition,Character character) { this.lock=lock; this.thisCondition=thisCondition; this.nextCondition=nextCondition; this.character=character; } public void run() { lock.lock(); try { for(int i=0;i<count;i++) { System.out.print(character); nextCondition.signal(); if(i<count) { try { thisCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } } } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { ReentrantLock reentrantLock=new ReentrantLock(); Condition conditionA=reentrantLock.newCondition(); Condition conditionB=reentrantLock.newCondition(); Thread threadA=new Thread(new PrintAB(reentrantLock,conditionA,conditionB,'A')); Thread threadB=new Thread(new PrintAB(reentrantLock,conditionB,conditionA,'B')); threadA.start(); Thread.sleep(100); threadB.start(); } }
第三种:
public class Demo3 { public static void main(String[] args) { final Print_ print = new Print_(); new Thread(new Runnable() { public void run() { for(int i=0 ;i<10 ;i++) { print.Print_A(); } } }).start(); new Thread(new Runnable() { public void run() { for(int i=0 ;i<10 ;i++) { print.Print_B(); } } }).start(); } } class Print_{ private boolean flag=true; public synchronized void Print_A(){ while(!flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.print("A"); flag=false; this.notify(); } public synchronized void Print_B(){ while(flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("B"); flag=true; this.notify(); } }