题目:有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C,要求, 同时启动三个线程, 按顺序输出ABC, 循环10次。
解法一(如果让程序不间断的反复运行,偶尔还是会出现死锁)
public class ThreeThreadPrintABC
{
private static Lock lock = new ReentrantLock();
private static Condition ac = lock.newCondition();
private static Condition bc = lock.newCondition();
private static Condition cc = lock.newCondition();
private static volatile int count = 0;
private static volatile boolean bRunning = false;
private static volatile boolean cRunning = false;
public static void main(String[] args)
{
System.out.println("Hello World!");
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.execute(new PrintC());
executor.execute(new PrintB());
executor.execute(new PrintA());
executor.shutdown();
}
private static class PrintA implements Runnable
{
public void run(){
//等待PrintB,PrintC运行一次,使得他们可以进入阻塞状态,
//否则可能A先执行ac.signal(),B再执行ac.await(),如此可能进入死锁。
while(!(bRunning && cRunning)){
//System.out.println("A");
}
while(true){
try{
lock.lock();
//通知PrintB打印B
ac.signal();
//System.out.println("tell B....");
//打印10次完成,结束
if(count == 10){
break;
}
System.out.print("A");
//System.out.println("wait for C....");
//等待PrintC通知开始下次打印循环
cc.await();
}catch(InterruptedException ex){
}finally{
lock.unlock();
}
}
}
}
private static class PrintB implements Runnable
{
public void run(){
//等待PrintC运行一次
while(!cRunning){
//System.out.println("B");
}
//System.out.println("B running!");
bRunning = true;
while(true){
try{
lock.lock();
//System.out.println("wait for A....");
//等待PrintA通知
ac.await();
//打印10次完成,结束
if(count == 10){
break;
}
System.out.print("B");
//通知PrintC打印B
bc.signal();
//System.out.println("tell C....");
}catch(InterruptedException ex){
}finally{
lock.unlock();
}
}
}
}
private static class PrintC implements Runnable
{
public void run(){
//System.out.println("C running!");
cRunning = true;
while(true){
try{
lock.lock();
//System.out.println("wait for B....");
//等待PrintB通知
bc.await();
System.out.println("C");
count++;
//通知PrintA打印A
cc.signal();
//System.out.println("tell A....");
//打印10次完成,结束
if(count == 10){
break;
}
}catch(InterruptedException ex){
}finally{
lock.unlock();
}
}
}
}
}
解法二
解题思路:要按顺序输出ABC, 循环10次,就要控制三个线程同步工作,也就是说要让三个线程轮流输出,直到10个ABC全部输出则结束线程。这里用一个Lock对象来控制三个线程的同步。用一个int型变量state标识由那个线程输出。
解法四
改编成java版(感觉比解法一更易懂,自己可能一开始想错方向了)
import java.util.*;
import java.util.concurrent.*;
public class ThreeThreadPrintABCSemaphore
{
private static Semaphore as = new Semaphore(1);
private static Semaphore bs = new Semaphore(0);
private static Semaphore cs = new Semaphore(0);
private static volatile int count = 0;
public static void main(String[] args)
{
System.out.println("Hello World!");
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.execute(new PrintC());
executor.execute(new PrintB());
executor.execute(new PrintA());
executor.shutdown();
}
private static class PrintA implements Runnable
{
public void run(){
while(true){
try{
//申请打印A许可
as.acquire();
if(count == 10){
bs.release();
break;
}
System.out.print("A");
}catch(InterruptedException ex){
}finally{
//A打印过之后发放一个打印B许可
bs.release();
}
}
}
}
private static class PrintB implements Runnable
{
public void run(){
while(true){
try{
//申请打印B许可
bs.acquire();
//打印10次完成,结束
if(count == 10){
cs.release();
break;
}
System.out.print("B");
}catch(InterruptedException ex){
}finally{
cs.release();
}
}
}
}
private static class PrintC implements Runnable
{
public void run(){
while(true){
try{
cs.acquire();
System.out.print("C");
count++;
//打印10次完成,结束
if(count == 10){
as.release();
break;
}
}catch(InterruptedException ex){
}finally{
as.release();
}
}
}
}
}