多线程循环打印ABC
主要是利用线程的wait()和notify()来实现
public class MyThread implements Runnable {
private String name;
private Object prev;
private Object mine;
private MyThread(String name,Object prev,Object mine){
this.name = name;
this.prev = prev;
this.mine = mine;
}
@Override
public void run() {
int count = 10;
while(count > 0){
synchronized (prev) {
synchronized (mine) {
System.out.println(name);
count--;
mine.notify();
}
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThread pa = new MyThread("A", c, a);
MyThread pb = new MyThread("B", a, b);
MyThread pc = new MyThread("C", b, c);
new Thread(pa).start();
new Thread(pb).start();
new Thread(pc).start();
}
}
整理下程序的思路:因3个线程要按照顺序打印ABC,那么应该是ThreadA->ThreadB->ThreadC->ThreadA如此循环,当运行ThreadA时,prev对象是c,mine对象是a,打印A,然后唤醒线程a,最后让当前线程c等待,则ThreadA进入等待(注意此时调用的prev.wait()虽然让线程进入了等待,但同时也释放了对象的锁,其他线程可以访问此同步方法)。ThreadB的prev对象是a,mine对象是b,打印B;而ThreadC的prev对象是b,mine对象是c;其实这种方式不一定能完全保证是ABC的顺序输出,因为看程序,B线程在等待a对象的锁,获取a的锁才能继续向下进行,而C线程在如果抢先运行的话,b的锁是不需要等待的,则直接等待a的锁,在ThreadA运行完毕释放锁后,若C线程率先获取a的锁的话,那么打印顺序就会遭到改变。所以若要让线程A、B、C按照顺序执行的话,一定要让3个线程按照顺序执行。更改程序为:
public class MyThread implements Runnable {
private String name;
private Object prev;
private Object mine;
private MyThread(String name,Object prev,Object mine){
this.name = name;
this.prev = prev;
this.mine = mine;
}
@Override
public void run() {
int count = 10;
while(count > 0){
synchronized (prev) {
synchronized (mine) {
System.out.println(name);
count--;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
mine.notify();
}
try {
prev.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Object a = new Object();
Object b = new Object();
Object c = new Object();
MyThread pa = new MyThread("A", c, a);
MyThread pb = new MyThread("B", a, b);
MyThread pc = new MyThread("C", b, c);
try {
new Thread(pa).start();
Thread.sleep(10);
new Thread(pb).start();
Thread.sleep(10);
new Thread(pc).start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
这样就能真正的实现,第一遍运行顺序为ThreadA打印A,然后ThreadA等待->ThreadB打印B,然后B等待->ThreadC打印C,然后C等待并唤醒A;以此循环打印了。
文章思路不是很清晰,主要还是学习别人写的东西,转化成自己能够理解的语言。努力学习中!
多线程循环打印ABC的更多相关文章
- Java多线程循环打印ABC的5种实现方法
https://blog.csdn.net/weixin_39723337/article/details/80352783 题目:3个线程循环打印ABC,其中A打印3次,B打印2次,C打印1次,循环 ...
- python 多线程实现循环打印 abc
python 多线程实现循环打印 abc 好久没写过python了, 想自己实践一下把 非阻塞版 import threading import time def print_a(): global ...
- 多线程循环打印数组 -- Java笔记
问题描述: 现有多个长度相同的数组,现要求使用多线程将数组内的数交替打印. 如: int[] ai = {1,2,3,4,5,6,7}; String[] ac = {"A",&q ...
- JAVA 多线程轮流打印ABC
采用Thread+Semaphore实现,思路很简单 import java.io.IOException; import java.util.concurrent.Semaphore; public ...
- python多线程交替打印abc以及线程池进程池的相关概念
import threading import sys import time def showa(): while True: lockc.acquire() #获取对方的锁,释放自己的锁 prin ...
- c++11 多线程依次打印ABC
并发 练习代码 #include <thread> #include <vector> #include <mutex> #include <iostream ...
- 用三个线程按顺序循环打印ABC三个字母
有两种方法:semaphore信号量和mutex互斥锁.需要注意的是C++11已经没有semaphore. C++ 并发编程(六):信号量(Semaphore) - 止于至善 - SegmentFau ...
- Java多线程wait和notify协作,按序打印abc
有一个经典的多线程面试题:启三个线程,按序打印ABC 上代码: package cn.javaBase.study_thread1; class MyRunnable1 implements Runn ...
- 迅雷笔试题 (JAVA多线程)启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC
题目:http://wenku.baidu.com/view/d66187aad1f34693daef3e8a.html 启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC. ...
随机推荐
- JavaScript_day01
1.变量声明 怎么声明变量? JavaScript中变量声明用的关键字是 var 变量名称. 变量名称命名有什么限制? 变量名称命名需规范,准则:不能以数字开头,不能含有特殊字符(css的属性),可以 ...
- vmware 虚拟机扩展 liunx系统硬盘空间
参考一下以下博客 https://www.cnblogs.com/yongdaimi/p/9050155.html https://blog.csdn.net/daemon_2017/article/ ...
- 2.Redis 入门介绍
A)入门概述: 1.是什么: Redis:REmote Dlctionary Server(远程字典服务器) 是完全开源免费的,用C语言编写的,遵循BSD协议,是一个高性能的(key/value) ...
- Unknown initial character set index '255' received from server. Initial client character 解决方法
Unknown initial character set index '255' received from server. Initial client character set can be ...
- 【基础数位DP-模板】HDU-2089-不要62
不要62 Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): Accepted Su ...
- 7月新的开始 - Axure学习01 - 元件库、元件交互样式设置
解释: Axure 属于原型制作里的霸道总裁 1.原型:原型模拟真实产品的功能与设计.用于在初期阶段测试产品的可行性与效果.来节省开发成本与周期. 2.线框图:在初期实现对产品的了解.实现产品的基本结 ...
- 指定js文件不使用 ESLint 语法检查
整个文件范围内禁止规则出现警告 将/* eslint-disable */放置于文件最顶部 /* eslint-disable */ alert('foo'); 在文件中临时禁止规则出现警告 将需要忽 ...
- 后端数据中含有html标签和css样式,前端如何转译展示样式效果。
后端含有html标签和css样式的数据: domain="<span style='color:red'>www.baidu.com</span>" (vu ...
- BZOJ 3931 / Luogu P3171 [CQOI2015]网络吞吐量 (最大流板题)
题面 中文题目,不解释: BZOJ传送门 Luogu传送门 分析 这题建图是显然的,拆点后iii和i′i'i′连容量为吞吐量的边,根据题目要求,111和nnn的吞吐量看作∞\infty∞. 然后用di ...
- javascript逻辑非(!/!!)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...