主要是利用线程的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的更多相关文章

  1. Java多线程循环打印ABC的5种实现方法

    https://blog.csdn.net/weixin_39723337/article/details/80352783 题目:3个线程循环打印ABC,其中A打印3次,B打印2次,C打印1次,循环 ...

  2. python 多线程实现循环打印 abc

    python 多线程实现循环打印 abc 好久没写过python了, 想自己实践一下把 非阻塞版 import threading import time def print_a(): global ...

  3. 多线程循环打印数组 -- Java笔记

    问题描述: 现有多个长度相同的数组,现要求使用多线程将数组内的数交替打印. 如: int[] ai = {1,2,3,4,5,6,7}; String[] ac = {"A",&q ...

  4. JAVA 多线程轮流打印ABC

    采用Thread+Semaphore实现,思路很简单 import java.io.IOException; import java.util.concurrent.Semaphore; public ...

  5. python多线程交替打印abc以及线程池进程池的相关概念

    import threading import sys import time def showa(): while True: lockc.acquire() #获取对方的锁,释放自己的锁 prin ...

  6. c++11 多线程依次打印ABC

    并发 练习代码 #include <thread> #include <vector> #include <mutex> #include <iostream ...

  7. 用三个线程按顺序循环打印ABC三个字母

    有两种方法:semaphore信号量和mutex互斥锁.需要注意的是C++11已经没有semaphore. C++ 并发编程(六):信号量(Semaphore) - 止于至善 - SegmentFau ...

  8. Java多线程wait和notify协作,按序打印abc

    有一个经典的多线程面试题:启三个线程,按序打印ABC 上代码: package cn.javaBase.study_thread1; class MyRunnable1 implements Runn ...

  9. 迅雷笔试题 (JAVA多线程)启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC

    题目:http://wenku.baidu.com/view/d66187aad1f34693daef3e8a.html 启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC. ...

随机推荐

  1. form-create教程:自定义布局,实现一行多个组件

    本文将介绍form-create如何自定义布局,实现一行多个组件 form-create 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成器.并且支持生成任何 Vue 组 ...

  2. 在nuxt中引入Font Awesome字体图标库

    介绍 在element-ui框架中提供了一些图标样式,但是种类比较少,所以在这里提供一套更完善的字体图标库Font Awesome(官方文档),下面就开始介绍如何在一个nuxt项目中使用这套字体库. ...

  3. Java基础加强-类加载器

    /*类加载器*/ 把.class文件从硬盘上加载出来,将类的字节码(二进制)加载到内存中 /*类加载器及其委托机制*/ Java虚拟机中可以安装多个类加载器(可以自己编写),系统默认三个主要类加载器, ...

  4. 《数据结构与算法之美》 <05>链表(下):如何轻松写出正确的链表代码?

    想要写好链表代码并不是容易的事儿,尤其是那些复杂的链表操作,比如链表反转.有序链表合并等,写的时候非常容易出错.从我上百场面试的经验来看,能把“链表反转”这几行代码写对的人不足 10%. 为什么链表代 ...

  5. 企业级自动化运维工具应用实战ansible

    公司计划在年底做一次大型市场促销活动,全面冲刺下交易额,为明年的上市做准备.公司要求各业务组对年底大促做准备,运维部要求所有业务容量进行三倍的扩容,并搭建出多套环境可以共开发和测试人员做测试,运维老大 ...

  6. 安装 ALC 解决 centos8 不能播放多媒体的问题

    装完centos8 后,发现看不到视频,听不到音乐,连web在线听音乐也不行.通过安装ALC可以解决. 1.三步安装VLC 这是 centos8 的安装包,曾使用 8 之前的版本安装是不成功的 sud ...

  7. Selenium(二)开发环境的搭建

    1.安装python的开发集成环境 我之前有写,可参考https://www.cnblogs.com/dydxw/p/10405797.html 2.使用selenium打开火狐浏览器 先从selen ...

  8. (二)AppScan使用教程

    1.新建扫描:一般选择 常规扫描 2.选择扫描的平台:web或app 3.扫描配置向导 ①配置URL和服务器 ②配置登录管理 在扫描的过程中,可能会不小心碰到退出按钮导致Appscan注销.因此,要登 ...

  9. python_tkinter弹出对话框2

    1.fledialog对话框 示例:askopenfilename(选择单个文件,获取文件路径) import tkinter # 导入消息对话框子模块 import tkinter.filedial ...

  10. nodejs常用框架使用样例

    Koa const Koa = require('koa'); const router = require('koa-router')(); const app = new Koa(); const ...