1. 程式人生 > >兩種方式的交替列印 基於Synchronized 與 ReentrantLock

兩種方式的交替列印 基於Synchronized 與 ReentrantLock

public class PrintABCTest {
	
	public static void main(String[] args) {
		PrintABC printABC = new PrintABC();
		new Thread(()->{
			for(int i = 1;i<11;i++){
				printABC.printA(i);
			}
		} , "A").start();
		
		new Thread(()->{
			for(int i = 1;i<11;i++){
				printABC.printB(i);
			}
		} , "B").start();
		
		new Thread(()->{
			for(int i = 1;i<11;i++){
				printABC.printC(i);
			}
		} , "C").start();
	}
	
}
class PrintABC{
	private Lock lock  = new ReentrantLock();
	
	private Condition conditionA = lock.newCondition();
	
	private Condition conditionB = lock.newCondition();
	
	private Condition conditionC = lock.newCondition();
	
	private int printStep = 1;
	
	public void printA(int i){
		lock.lock();
		try {
			while(printStep != 1){
				conditionA.await();
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< "+i);
			printStep = 2;
			conditionB.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void printB(int i){
		lock.lock();
		try {
			while(printStep !=2){
				conditionB.await();
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< "+i);
			printStep = 3;
			conditionC.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public void printC(int i){
		lock.lock();
		try {
			while(printStep !=3){
				conditionC.await();
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< "+i);
			printStep = 1;
			conditionA.signal();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
}

或者另一種方式

public class PrintABCTest2 {
	
	public static void main(String[] args) {
		PrintABC2 printABC = new PrintABC2();
		new Thread(()->{
			for(int i = 0;i<10;i++){
				printABC.printA();
			}
		} , "A").start();
		
		new Thread(()->{
			for(int i = 0;i<10;i++){
				printABC.printB();
			}
		} , "B").start();
		
		new Thread(()->{
			for(int i = 0;i<10;i++){
				printABC.printC();
			}
		} , "C").start();
	}
	
}
class PrintABC2{
	
	private int printStep = 1;
	private Object lock = new Object();
	public void printA(){
		synchronized (lock) {
			while(printStep != 1){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< ");
			printStep = 2;
			lock.notifyAll();
		}
	}
	
	public void printB(){
		synchronized (lock) {
			while(printStep != 2){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< ");
			printStep = 3;
			lock.notifyAll();
		}
	}
	
	public void printC(){
		synchronized (lock) {
			while(printStep != 3){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(" >>> "+Thread.currentThread().getName()+" <<< ");
			printStep = 1;
			lock.notifyAll();
		}
	}
}