启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5 然后是线程2打印6,7,8,9,10 然后是线程3打印11,12,13,14,15.接着再由线程1打印16,17,18,19,20....

1 传统锁synchronized实现

        启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5 然后是线程2打印6,7,8,9,10 然后是线程3打印11,12,13,14,15.接着再由线程1打印16,17,18,19,20…依次类推, 直到打印到60。
        提示:定义一个同步方法,在方法中使用循环的方式输出连续的5个数字,方法执行前,可以通过标记的方式判断是否是当前线程应该执行,如果是,则执行输出逻辑,如果不是,则wait进入等待队列,在方法执行结束前,必须使用notifyAll唤醒其他所有线程。

public class Problem02 {
 
	public static void main(String[] args) {
		final Hander hander = new Hander();//实例化Hander对象
 		//循环建立三个线程.并启动
		for (int i = 0; i < 3; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					for(int j=0;j<5;j++) {
						hander.print(Thread.currentThread().getName());
					}
				}
			}, i + "").start();
		}
	}
}
 
class Hander {
   //打印的数字 变量
	private int no = 1;
	//判断变量
	private int status = 0;
	
	// 将该方法上锁
	public synchronized void print(String threadName) {
		int threadIndex = Integer.parseInt(threadName);//将threadName转换为int
		//不相等则进入等待
		while (threadIndex != status) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.print("Thread-"+threadName+" : ");//输出线程名
		//打印数字循环
		for (int count = 0; count < 5; count++, no++) {
			if (count > 0) {
				System.out.print(",");
			}
			System.out.print(no);
		}
		System.out.println();
		status = (status + 1) % 3;//改变status的值
		this.notifyAll();//唤醒其他线程
	}
}

启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5 然后是线程2打印6,7,8,9,10 然后是线程3打印11,12,13,14,15.接着再由线程1打印16,17,18,19,20....

2 lock可重入锁实现 (以下内容有毒,慎重阅读,我居然写完了,我的天,佩服自己三秒钟!!! )

        启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5 然后是线程2打印6,7,8,9,10 然后是线程3打印11,12,13,14,15.接着再由线程1打印16,17,18,19,20…依次类推, 直到打印到60。
        提示:定义一个类,其中定义三个方法,分别用于打印符合要求的数字。定义三个condition条件,通过线程编号来判断应该是哪一个线程执行输出逻辑,哪一个线程应该执行await等待逻辑。注意,一定要在finally中unlock释放锁,且在释放锁之前要使用condition的signalAll唤醒其他等待线程。

public class T {

	int num = 0;
	int index = 0;
	Lock lock = new ReentrantLock(true);
	Condition c1 = lock.newCondition();
	Condition c2 = lock.newCondition();
	Condition c3 = lock.newCondition();
	
	void m1(){
		int threadIndex = Integer.parseInt(Thread.currentThread().getName());
		try{
			lock.lock();
			while(threadIndex != index){
				c1.await();
			}
			System.out.print(Thread.currentThread().getName() + " - " + index + " : ");
			for(int i = 1; i <= 5; i++){
				System.out.print(++num + ",");
			}
			System.out.println();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			index = (index + 1) % 3;
			c2.signalAll();
			c3.signalAll();
			lock.unlock();
		}
	}
	void m2(){
		int threadIndex = Integer.parseInt(Thread.currentThread().getName());
		try{
			lock.lock();
			while(threadIndex != index){
				c2.await();
			}
			System.out.print(Thread.currentThread().getName() + " - " + index + " : ");
			for(int i = 1; i <= 5; i++){
				System.out.print(++num + ",");
			}
			System.out.println();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			index = (index + 1) % 3;
			c1.signalAll();
			c3.signalAll();
			lock.unlock();
		}
	}
	void m3(){
		int threadIndex = Integer.parseInt(Thread.currentThread().getName());
		try{
			lock.lock();
			while(threadIndex != index){
				c3.await();
			}
			System.out.print(Thread.currentThread().getName() + " - " + index + " : ");
			for(int i = 1; i <= 5; i++){
				System.out.print(++num + ",");
			}
			System.out.println();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			index = (index + 1) % 3;
			c2.signalAll();
			c1.signalAll();
			lock.unlock();
		}
	}
	
	public static void main(String[] args) {
		final T t = new T();
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int j=0;j<4;j++) {
					t.m1();
				}
			}
		}, "0").start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int j=0;j<4;j++) {
					t.m2();
				}
			}
		}, "1").start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				for(int j=0;j<4;j++) {
					t.m3();
				}
			}
		}, "2").start();
	}	
}