Java多线程通信|Java多线程通信 练习题(写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z)

该练习题需要借助Java传统的线程通信的知识。
首先,我们创建了一个打印类Print,该类中分别实现了打印数字printNums()方法、以及打印字符printChars()方法。

class Print { private boolean flag=false; public synchronized void writeNums() { try { for(int i=1; i<=26; ) { //如果flag为true,说明数字已经打印了,打印数字线程阻塞 if(flag) { wait(); } else { System.out.print(i*2-1); System.out.print(i*2); //将标识设为true,表明打印数字线程已执行 flag=true; i++; //唤醒其他线程 notifyAll(); } } } catch (InterruptedException ex) { ex.printStackTrace(); } } public synchronized void writeChars() { try { for(int i='A'; i<='Z'; ) { //如果flag为false,说明字符已经打印了,打印字符线程阻塞 if(!flag) { wait(); } else { System.out.print((char)i); //将标识设为true,表明打印字符线程已执行 flag=false; i++; //唤醒其他线程 notifyAll(); } } } catch (InterruptedException ex) { ex.printStackTrace(); } } }

在该Print类中,我们通过用synchronized关键词修饰这两个方法来把这两个方法变成同步方法。由于同步方法的同步监视器为调用该方法的类实例,所以在这两个方法中可以直接使用wait()、notifyAll()方法来实现对程序的控制。方法中的flag作为一个标记,用来标记当前时候已打印数字。当程序进入printNums()方法后,如果flag为true,则表明当前已经打印数字,程序调用wait()方法阻塞;否则程序上下执行打印数字操作,当打印数字操作完成后,系统将flag设为true,然后调用notifyAll()来唤醒其他被阻塞的线程——如果系统中有打印数字线程,打印数字线程也会被唤醒,但该打印数字线程执行到该方法的wait()处时再次进入阻塞状态,只有执行打印字符方法printChars()的打印字符线程才可以向下执行。同理,打印字符线程的运行流程也是如此。
打印数字、打印字符操作都被Print类进行了封装,所以在打印数字以及打印字符线程中,只需要用Print对象调用对应的方法即可。打印数字线程如下:
class PrintNumsThread extends Thread { private Print p; public PrintNumsThread(Print p) { this.p=p; } public void run() { p.writeNums(); } }

打印字符线程如下:
class PrintCharsThread extends Thread { private Print p; public PrintCharsThread(Print p) { this.p=p; } public void run() { p.writeChars(); } }

最后,给出测试类:
public class PrintTest { public static void main(String[] args) { Print p=new Print(); new PrintNumsThread(p).start(); new PrintCharsThread(p).start(); } }

下面展示一下我运行的结果吧!
【Java多线程通信|Java多线程通信 练习题(写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z)】Java多线程通信|Java多线程通信 练习题(写两个线程,其中一个线程打印1-52,另一个打印A-Z,打印顺序为12A34B56C....5152Z)
文章图片

    推荐阅读