java三线程循环有序打印ABC
迅雷笔试题:
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。
解决思路:每个线程运行时先检查他依赖的线程是否已完成工作,线程B依赖线程A的完成,线程C依赖线程B和线程A的完成,线程A依赖线程C的完成。如果当前线程依赖的线程没有执行完,则阻塞当前线程直到条件满足再执行。
Condition.await()会使当前线程暂时阻塞,并释放ReentrantLock锁.
Condition.signalAll()会通知激活Condition.await()而阻塞的线程,这时被激活的线程就会继续检查(通过while循环))是否满足条件,如果满足而且再次获得ReentrantLock锁就能继续运行,否则继续等待。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class ThreadDemo implements Runnable { private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
//标记线程A的状态,true为刚执行完。为什么要两个变量?因为只使用一个变量,当线程A执行完后,a为true,B线程就会不停执行
//所以线程B执行要执行必须满足a==true&&a2==true
private volatile Boolean a = false, a2 = false;
//标记线程B的状态,true为刚执行完。
private volatile Boolean b = false;
//标记线程C的状态,true为刚执行完。
private volatile Boolean c = true; @Override
public void run() {
String name = Thread.currentThread().getName();
lock.lock();
//进入临界区
try {
for (int i = 0; i < 10; i++) {
if (name.equals("B")) {
//只有a和a2同时为true时才打印B,否则阻塞当前线程
while (!a || !a2) {
condition.await();//条件不满足,暂时阻塞线程,暂时释放lock
}
b = true;
a2 = false;
} else if (name.equals("C")) {
while (!a || !b) {
condition.await();
}
c = true;
b = false;
} else if (name.equals("A")) {
while (!c) {
condition.await();
}
a = true;
a2 = true;
b = false;
c = false;
}
System.out.print(name);
condition.signalAll();//通知正在等待的线程,此时有可能已经满足条件
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();// 记得要释放锁
}
} public static void main(String[] args) throws InterruptedException {
ThreadDemo task = new ThreadDemo();
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
Thread thread3 = new Thread(task);
thread1.setName("A");
thread2.setName("B");
thread3.setName("C");
thread1.start();
thread2.start();
thread3.start();
} }
下面是更简单的实现方法:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class ThreadDemo implements Runnable { private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private int state = 0; @Override
public void run() {
String name = Thread.currentThread().getName();
lock.lock();
// 进入临界区
try {
for (int i = 0; i < 10; i++) {
if (name.equals("B")) {
// 只有a和a2同时为true时才打印B,否则阻塞当前线程
while (state % 3 != 1) {
condition.await();// 条件不满足,暂时阻塞线程,暂时释放lock
}
} else if (name.equals("C")) {
while (state % 3 != 2) {
condition.await();
}
} else if (name.equals("A")) {
while (state % 3 != 0) {
condition.await();
}
}
state++;
System.out.print(name);
condition.signalAll();// 通知正在等待的线程,此时有可能已经满足条件
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();// 记得要释放锁
}
} public static void main(String[] args) throws InterruptedException {
ThreadDemo task = new ThreadDemo();
Thread thread1 = new Thread(task);
Thread thread2 = new Thread(task);
Thread thread3 = new Thread(task);
thread1.setName("A");
thread2.setName("B");
thread3.setName("C");
thread1.start();
thread2.start();
thread3.start();
} }
java三线程循环有序打印ABC的更多相关文章
- java 三种循环及注意事项
package debug; public class Demo8 { public static void main(String[] args) { //采用for循环打印10次Java好 for ...
- java 三个循环的优缺点
package cc.knms.appservice.test; import java.text.ParseException; import java.util.ArrayList; import ...
- 【Java学习笔记之六】java三种循环(for,while,do......while)的使用方法及区别
第一种:for循环 循环结构for语句的格式: for(初始化表达式;条件表达式;循环后的操作表达式) { 循环体; } eg: class Dome_For2{ public st ...
- 线程轮循打印ABC...
package com.java.concurrent; import java.util.concurrent.locks.Condition; import java.util.concurren ...
- Java多线程wait和notify协作,按序打印abc
有一个经典的多线程面试题:启三个线程,按序打印ABC 上代码: package cn.javaBase.study_thread1; class MyRunnable1 implements Runn ...
- Java的三种循环:1、for循环 2、while循环 3、do...while循环
Java的三种循环 Java三种循环结构: 1.for循环 2.while循环 3.do...while循环 循环结构组成部分:1.条件初始化语句,2.条件判断语句 , 3.循环体语句,4.条件控制语 ...
- 迅雷笔试题 (JAVA多线程)启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC
题目:http://wenku.baidu.com/view/d66187aad1f34693daef3e8a.html 启动三个线程,分别打印A B C,现在写一个程序 循环打印ABCABCABC. ...
- Java多线程循环打印ABC的5种实现方法
https://blog.csdn.net/weixin_39723337/article/details/80352783 题目:3个线程循环打印ABC,其中A打印3次,B打印2次,C打印1次,循环 ...
- 三个线程ABC,交替打印ABC
转载与:https://www.cnblogs.com/x_wukong/p/4009709.html 创建3个线程,让其交替打印ABC . 输出如下: ABCABCABCABC. 方法:使用syn ...
随机推荐
- html中的body标签
<head>标签代表的是页面的"头部",而<body>标签代表的就是页面的"身体"了.如果说<html>标签定义了网页的开始 ...
- Android 常用的快捷键(随时更新)
android studio 是google出的一款好用不贵的ide,好像是powerd by idea的那个公司,反正风格上差不多.下面是android studio常用的快捷键设置,记录一下自己用 ...
- postfix 不记录日志的问题解决方法
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- [转]SpringMVC日期类型转换问题三大处理方法归纳
http://blog.csdn.net/chenleixing/article/details/45190371 前言 我们在SpringMVC开发中,可能遇到比较多的问题就是前台与后台实体类之间日 ...
- iOS 根据文件名获取到文件路径
根据文件名来获取文件路径(Document目录下) //根据文件名来获取文件路径 - (NSString *)dataFilePath:(NSString *)sender { NSArray *pa ...
- 从零开始学android开发-获取TextView的值
昨日写一个Android Demo,逻辑大概是从TextView获取其中的值,然后处理后再放回TextView中.整个处理过程是由一个Button的OnClick触发的. 可是在调试的过程中,一点击B ...
- 图解iPhone开发新手教程
如今的智能手机越来越风行了,当中尤以Apple的iPhone和Google的Android系统最为流行,这里我将向大家介绍iPhone开发的基础知识.为了便于刚開始学习的人尽快上手,我尽量以代码加截图 ...
- mysql聚合函数
1.统计一下插入的数据总数 SELECT COUNT(giftCertificateId) AS number FROM gift_certificate WHERE giftCertificateN ...
- 比较js中创建对象的几种方式
1.工厂模式 function createObj(name, sex){ var obj = new Object(); obj.name = name; obj.sex = sex; obj.sa ...
- iframe实现面页无刷新提交表单
一.表单提交到了哪里? 这似乎是个无知的问题,我们都知道表单提交到服务器,java,php,asp等服务器,然后由服务器去读.那么之后呢,服务器总要返回点什么吧,要么返回 一个xml或json数据,要 ...