题目:线程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();
}
}