有三个线程ABC,现要连续打印这三个线程,结果显示为ABCABC…连续打印十次的解决方案。
方案1
利用ReentrantLock重入锁的Condition对象实现等待/通知。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ABCTest {
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
Condition ab = reentrantLock.newCondition();
Condition bc = reentrantLock.newCondition();
Condition ca = reentrantLock.newCondition();
new Thread(new ABCThread(reentrantLock,ca,ab),"A").start();
new Thread(new ABCThread(reentrantLock,ab,bc),"B").start();
new Thread(new ABCThread(reentrantLock,bc,ca),"C").start();
//此时要先唤起第一个线程,因为调用的ABCThread类中的x在进入后首先进入的是阻塞状态
//因此需要在此先唤醒第一个线程
reentrantLock.lock();
ca.signal();
reentrantLock.unlock();
}
}
ABCThread类代码实现:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ABCThread implements Runnable{
private ReentrantLock lock;
private Condition acondition;
private Condition ccondition;
public ABCThread(ReentrantLock lock, Condition acondition, Condition ccondition) {
this.lock = lock;
this.acondition = acondition;
this.ccondition = ccondition;
}
@Override
public void run() {
int i=0;
while(i<10){
//加锁
lock.lock();
try {
//接收到上一个线程通知则继续执行,否则进入阻塞
acondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(Thread.currentThread().getName()+"");
//通知下一个线程
ccondition.signal();
i++;
//释放锁
lock.unlock();
}
}
}
运行结果:
方案2
利用wait/notifyAll来进行线程间的通信
class ABCThread implements Runnable{
int i = 1;
@Override
public void run() {
while (true){
synchronized (this){
this.notifyAll();
if (i <= 30 ){
System.out.print(Thread.currentThread().getName()+" ");
i++;
}else {
break;
}
try {
this.wait();//打印过数据的线程等待 必须等到没打印过数字的拿到锁了才能唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class test {
public static void main(String[] args) {
ABCThread abc= new ABCThread ();
Thread thread1 = new Thread(abc,"A");
Thread thread2 = new Thread(abc,"B");
Thread thread3 = new Thread(abc,"C");
thread1.start();
thread2.start();
thread3.start();
}
}
打印结果: