实现交替打印的核心思想就是:采用同一对象锁,进行上锁解锁操作,从而实现两个线程交替执行。当然,实现的方式有很多种。可以采用wait()/notify(),但我这里采用Lock和Condition
上锁的话,肯定是要用同一对象的锁,所以我们就定义一个类,表示那两个线程类共享它的对象
class Obj
{
//模拟cpu占用情况
public boolean cpu=false;
public boolean cpu2=false;
}
现在,我们定义两个线程类ThreadA和ThreadB,A打印偶数,B打印奇数,这两个类几乎一样,只有些许差异
class ThreadA implements Runnable
{
private Obj obj;
private Lock lock;
private Condition condition;
private int index=0;//偶数从0开始
}
class ThreadB implements Runnable
{
private Obj obj;
private Lock lock;
private Condition condition;
private int index=1;//奇数从1开始
}
同一对象锁我们已经说过了,交替打印的过程应该是:线程A打印,线程B等待;线程B打印,线程A等待。那么当一个线程执行之后如何通知等待线程呢,答:signal(),就好像发个信号给等待线程,说你可以执行了。那由谁来通知呢?还是需要一个对象——Condition对象,请注意Condition对象也是需要同一个哦!既然如此,那么两个线程类的构造函数就知晓啦:
public ThreadA(Obj,obj,Lock lock,Condition condition)
{
this.obj=obj;
this.lock=lock;
this.condition=condition;
}
class ThreadB(Obj,obj,Lock lock,Condition condition)
{
this.obj=obj;
this.lock=lock;
this.condition=condition;
}
根据前面的思路分析,线程执行体就不难写出
线程A:
@Override
public void run() {
lock.lock();
try{
while(true)
{
if(obj.cpu2)//线程2正在占用CPU,线程A进入等待
condition.await();
else{
obj.cpu2=true;
System.out.println("A: "+x);
x+=2;
Thread.sleep(100);
}
obj.cpu=false;//线程1不可以使用CPU
condition.signal();
}
}catch (Exception e)
{
e.printStackTrace();
}finally {
lock.unlock();
}
}
线程B:
@Override
public void run() {
lock.lock();
try{
while(true)
{
if(obj.cpu)//线程1正在占用CPU,线程B进入等待
condition.await();
else{
obj.cpu=true;
System.out.println("B: "+x);
x+=2;
Thread.sleep(100);
}
obj.cpu2=false;//线程2不可以使用CPU
condition.signal();
}
}catch (Exception e)
{
e.printStackTrace();
}finally {
lock.unlock();
}
}
主函数:
public static void main(String[] agrs)
{
Obj obj=new Obj();
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();
new Thread(new ThreadA(obj,lock,condition)).start();
new Thread(new ThreadB(obj,lock,condition)).start();
}