编写一段代码,实现两个线程,一个线程打印1~ 52,另一个线程打印A~Z,其中打印顺序是12A34B…5152Z。编写测试代码,输出打印结果。
- 提示:
- await()方法会抛出必检异常,所以需要进行声明或捕获;
- 如果内部类是静态的,使用 new 外部类名.内部类构造方法创建内部类对象;
- 如果内部类是非静态的,使用new 外部类构造方法.new 内部类构造方法创建内部类对象;
- 如果类没有显示声明构造方法,会被自动分配默认无参构造方法(方法体为空);
- ()->print.printC('A', 'Z') 和 ()->print.printN(1, 52) 是Lamda表达式,因为run()方法没有参数,所以使用()表示。
package pack2;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestPrint {
public static void main(String[] args) {
//使用Executors的静态方法返回线程数为2的线程池
ExecutorService exService = Executors.newFixedThreadPool(2);
Print print = new TestPrint().new Print();//创建一个内部类
exService.execute(()->print.printC('A', 'Z'));//执行输出'A'~'Z'的字符
exService.execute(()->print.printN(1, 52));//执行输出1~52的数字
exService.shutdown(); //关闭线程池(会先执行完所有未完成的线程)
}
//内部类
private class Print{
private Lock lock = new ReentrantLock(true); //创建一个公平策略的锁
private Condition c1 = lock.newCondition(); //返回一个锁创建的条件并赋值
private Condition c2 = lock.newCondition();
//输出字符方法
public void printC(char start, char end) {
lock.lock(); //上锁
try {
c2.await(); //c2调用等待方法,目的是开始时输出数字
for (int i = (int)start; i <= (int)end; i++) {
System.out.print((char)i);
c1.signal(); //唤醒c1(c1代表输出数字的线程)
c2.await(); //c2等待(c2代表输出字符的线程)
}
}catch (Exception e) {
}finally {
lock.unlock(); //释放锁
}
}
//输出数字方法
public void printN(int start, int end) {
lock.lock();
try {
for (int i = start; i <= end; i++) {
System.out.print(i);
if(i % 2 == 0) {//如果求余2等于0(已输出两个数字)
c2.signal(); //唤醒c2
c1.await(); //c1等待
}
}
}catch (Exception e) {
}finally {
lock.unlock();
}
}
}
}