ReentrantLock实现多线程交替打印奇偶数

关于ReentrantLock的实现原理,详见这篇:https://github.com/crossoverJie/JCSprout/blob/master/MD/ReentrantLock.md

ReentrantLock实现交替打印奇偶数,就是开两个线程,一个打印奇数,一个用于打印偶数。
为什么要用ReentrantLock呢,因为这里交替打印(线程交替执行),需要对共享变量flag进行反复的加锁。所以如果用synchronized来进行同步的话,可能会造成自己阻塞自己,最后形成死锁。所以这里用到了重入锁ReentrantLock。

下面贴上代码:

package actual;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TwoThread {
	
	private int start = 1;
	
	//对 flag 的写入虽然加锁保证了线程安全,但读取的时候由于 不是 volatile 所以可能会读取到旧值
	private volatile boolean flag = false;
	
	//重入锁,ReentrantLock
	private final static Lock lock = new ReentrantLock();
	
	public static void main(String[] args){
		TwoThread twoThread = new TwoThread();
		
		Thread t1 = new Thread(new JiNum(twoThread));
		t1.setName("t1");
		
		Thread t2 = new Thread(new OuNum(twoThread));
		t2.setName("t2");
		
		t1.start();
		t2.start();
	}
	
	//奇数线程
	public static class JiNum implements Runnable{

		private TwoThread number;
		
		public JiNum(TwoThread number){
			this.number = number;
		}
		
		@Override
		public void run() {
			while(number.start <= 100){
				if(!number.flag){
					try{
						lock.lock();
						System.out.println(Thread.currentThread().getName() + "+-+" + number.start);
						number.start ++ ;
						number.flag = true;
					}finally{
						lock.unlock();
					}
				}
			}
		}
		
	}
	
	//偶数线程
	public static class OuNum implements Runnable{

		private TwoThread number;
		
		public OuNum(TwoThread number){
			this.number = number;
		}
		
		@Override
		public void run() {
			while(number.start <= 100){
				if(number.flag){
					try{
						lock.lock();
						System.out.println(Thread.currentThread().getName() + "+-+" + number.start);
						number.start ++ ;
						number.flag = false;
					}finally{
						lock.unlock();
					}
				}
			}
		}
	}
}

结果:
ReentrantLock实现多线程交替打印奇偶数