多线程循环打印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. ...
随机推荐
- 线程池工具ThreadPoolExecutor
JDK1.5中引入了强大的concurrent包,其中最常用的莫过了线程池的实现ThreadPoolExecutor,它给我们带来了极大的方便,但同时,对于该线程池不恰当的设置也可能使其效率并不能达到 ...
- SpringCloud之Config配置中心+BUS消息总线原理及其配置
一.配置中心作用 在常规的开发中,每个微服务都包含代码和配置.其配置包含服务配置.各类开关和业务配置.如果系统结构中的微服务节点较少,那么常规的代码+配置的开发方式足以解决问题.当系统逐步迭代,其微服 ...
- python 解析Hdfs上的数据文件
python想直接读取hadoop上的文件内容,一番操作,头发掉了几根,也没能解析出来parquet文件类型的文件. 本博文简单讲解一下TEXTFILE文件格式的解析: 需要安装模块hdfs from ...
- 二零一八阿里p7笔试116题
1. junit用法,before,beforeClass,after, afterClass的执行顺序 2. 分布式锁 3. nginx的请求转发算法,如何配置根据权重转发 4. 用hashmap实 ...
- Kubernetes 的 Client Libraries 的使用
说明 kubernetes 估计会成为 linux 一样的存在,client-go 是它的 go sdk,client-go/examples/ 给出了一些用例,但是数量比较少. api Resour ...
- C和指针--命令行参数
1.命令行参数 C程序的main函数具有两个形参,第1个通常称为argc,它表示命令行参数的数目.第2个称为argv,它指向一组参数值.由于参数的数目并没有内在的限制,所以argv指向这组参数值(本质 ...
- Django权限和认证模块的解读
from rest_framework.views import APIView 找到APIView中的dispatch方法 class MyAuth: def authenticate(self): ...
- Maven打包Web项目成war包——4
1. 需要安装maven 的war插件支持 在pom.xml里面配置war插件 2. 运行命令: mvn clean package 3.部署到Tomcat下面发布,并访问!
- linux tar打包压缩排除某个目录或文件
用tar打包时想剔除打包目录中的某个子目录或文件: 比如你想打包/home这个目录,但是/home/afish/目录和/home/www/afish.php文件你都不想打包,方法是: tar -zcv ...
- python获取本机的IP
转载:https://www.cnblogs.com/whu-2017/p/8986842.html 方法一: 通常使用socket.gethostbyname()方法即可获取本机IP地址,但有时候获 ...