朋友最近去公司应聘,遇到了这么一道面试题,利用多线程循环打印ABC,刚好我也在学习多线程,看了网上的一些例子,结合自己的理解,编写了一个例子,与大家一起探讨;该例子使用到synchronized(对象同步锁),wait(),notifyAll()是两个定义在Object类里的方法,可以用来控制线程的状态。 这两个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
- 如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
- 如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
【多线程循环打印ABC】实现思路:
1、新建一个打印类PrintABC.java,处理打印ABC 业务逻辑;
2、 新建三个线程类,分别为:PrintAThread,PrintBThread,PrintCThread分别执行打印方法;开启三个线程,每个线程一次打印一个字母(PrintAThread打印 A,PrintBThread打印B,PrintCThread打印C),并且按照一定的顺序打印,当打印A的时候,其他线程处于阻塞状态,打印完A以后,将线程解锁,让打印B的那个线程开启,其他线程处于阻塞状态,同理打印C的时候,阻塞其他线程,这三个线程顺序循环,就达到顺序多次打印ABC的目的了;
打印类PrintABC.java:
class PrintABC {
private boolean printAThread = true;
private boolean printBThread = false;
private boolean printCThread = false;
public void excute() {
synchronized (this) {
while (!printAThread) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("A");
this.printAThread = false;
this.printBThread = true;
this.printCThread = false;
notifyAll();
}
}
public void excute2() {
synchronized (this) {
while (!printBThread) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print("B");
this.printAThread = false;
this.printBThread = false;
this.printCThread = true;
notifyAll();
}
}
public void excute3() {
synchronized (this) {
while (!printCThread) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("C");
this.printAThread = true;
this.printBThread = false;
this.printCThread = false;
notifyAll();
}
}
}
线程类PrintAThread.java:
class PrintAThread extends Thread {
private PrintABCprintABC ;
public PrintAThread(PrintABCprintABC ) {
this.printABC = printABC ;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
this.printABC .excute();
}
}
}
线程类PrintBThread.java:
class PrintBThread extends Thread {
private PrintABCprintABC ;
public PrintAThread(PrintABCprintABC ) {
this.printABC = printABC ;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
this.printABC .excute2();
}
}
}
线程类PrintCThread.java:
class PrintCThread extends Thread {
private PrintABC printABC ;
public PrintAThread( PrintABC printABC ) {
this. printABC = printABC ;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
this. printABC .excute3();
}
}
} 测试类PrintABCThreadTest.java
public class PrintABCThreadTest {
public static void main(String[] args) {
ReaderABC readerABC = new ReaderABC();
new PrintAThread(readerABC).start();
new PrintBThread(readerABC).start();
new PrintCThread(readerABC).start();
}
}
最终控制台打印结果如下:
文章图片
例子结束,如有错漏,请大家指出,谢谢!
备注:多线程,对象锁,线程等待, 通知相关知识都是编程比较重要的一部分,希望大家能掌握
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)