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 ...
随机推荐
- Sass 默认样式库
Sass 默认初始化样式库 @charset "utf-8"; // 变量存储 // 字体Unicode编码 微软雅黑:\5FAE\8F6F\96C5\9ED1 , 宋体:\5B8 ...
- 剑指OFFER之二叉树中和为某一值的路径(九度OJ1368)
题目描述: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 输入: 每个测试案例包括n+1行: 第一行为2 ...
- iOS 限制textField输入的长度
1.电话号码(带3-3-4效果) //指定代理 self.phoneTextField.delegate = self; //当编辑改变的时候,进行字符校验 [self.phoneTextField ...
- ServletContext1
---------------ConfigServlet.java----------- protected void doGet(HttpServletRequest request, HttpSe ...
- 【转】linux中的sed命令
转自:http://www.cnblogs.com/shineshqw/articles/1978122.html 功能说明: 利用script来处理文本文件. 语 法:sed [-hnV][-e&l ...
- JSON数据格式以及与后台交互数据转换实例
/* 作者:烟大阳仔 时间:20131013 介绍:主要了解一下json的格式,看看数据是怎么存储的 */ <!DOCTYPE html PUBLIC "-//W3C//DTD HTM ...
- paip.mysql备份慢的解决
paip.mysql备份慢的解决.txt 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...
- [Heroku] How to pull, push changes
1. First you need to login heroku: heroku login 2. Then you need to download the code: heroku git:cl ...
- springMVC整合xStream
一. 简单介绍: xStream能够轻易的将Java对象转换成xml.JSON.本篇博客将使用springMVC整合利用xStream转换xml. 关于xStream使用的博文:http://blog ...
- kernel debuging
http://blog.csdn.net/XscKernel/article/category/1276234