002 两个线程以指定步长交替打印数字与字母

题目:线程A负责打印数字,线程B负责打印字母,以指定步长n,每打印n个数字,则紧跟着打印一个字母。若字母已打印完,则紧接着仅打印数字即可,反之亦然。例如数字打印1~52,字母打印A-Z,则预期输出应为如下:

12A34B56C…4950Y5152Z

分析:本质上是利用线程的通信,来控制线程之间的交替执行。

          1、即A每打印n次,就通知B打印一次;

          2、线程B每打印一次,就通知线程A又可以打印了;

          3、不论是线程A,还是线程B,执行完毕后,都必须通知对方不必再按照原有的规则打印;

实现:线程间的通信,采用共享变量的值的变化来实现。执行块的安全性,采用Lock锁实现。

代码如下:

package com.navy.volatileDemo;

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


public class PrintNumberAndChar {
	
	private static Lock lock = new ReentrantLock();
	
	private static final int step = 2;
	
	private static int prints = 0;
	
	private static boolean isPrintNumberFinish = false;
	
	private static boolean isPrintCharFinish = false;
	
	private static class PrintNumber implements Runnable{
		private int max;
		private int min;
		
		public PrintNumber(int min, int max) {
			this.min = min;
			this.max = max;
		}
		
		@Override
		public void run() {
			while(min <= max){
				lock.lock();
				try{
					if(prints < step || isPrintCharFinish){
						System.out.print(min++);
						prints++;
					}
				}
				finally{
					lock.unlock();
				}
			}
			isPrintNumberFinish = true;
		}
	}
	
	private static class PrintChar implements Runnable{
		
		private char max;
		private char min;
		
		public PrintChar(char min, char max) {
			this.min = min;
			this.max = max;
		}
		
		@Override
		public void run() {
			while(min <= max){
				lock.lock();
				try{
					if(prints == step || isPrintNumberFinish){
						System.out.print(min++);
						prints = 0;
					}
				}
				finally{
					lock.unlock();
				}
			}
			isPrintCharFinish = true;
		}
	}
	
	public static void main(String[] args) {
		new Thread(new PrintNumber(1, 52), "printNumber").start();
		new Thread(new PrintChar('A', 'Z'), "printChar").start();
	}
}

 

你可能感兴趣的:(Java线程)