迅雷笔试题:

编写一个程序,开启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的更多相关文章

  1. java 三种循环及注意事项

    package debug; public class Demo8 { public static void main(String[] args) { //采用for循环打印10次Java好 for ...

  2. java 三个循环的优缺点

    package cc.knms.appservice.test; import java.text.ParseException; import java.util.ArrayList; import ...

  3. 【Java学习笔记之六】java三种循环(for,while,do......while)的使用方法及区别

    第一种:for循环 循环结构for语句的格式:       for(初始化表达式;条件表达式;循环后的操作表达式) { 循环体;    } eg: class Dome_For2{ public st ...

  4. 线程轮循打印ABC...

    package com.java.concurrent; import java.util.concurrent.locks.Condition; import java.util.concurren ...

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

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

  6. Java的三种循环:1、for循环 2、while循环 3、do...while循环

    Java的三种循环 Java三种循环结构: 1.for循环 2.while循环 3.do...while循环 循环结构组成部分:1.条件初始化语句,2.条件判断语句 , 3.循环体语句,4.条件控制语 ...

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

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

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

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

  9. 三个线程ABC,交替打印ABC

    转载与:https://www.cnblogs.com/x_wukong/p/4009709.html 创建3个线程,让其交替打印ABC . 输出如下:  ABCABCABCABC. 方法:使用syn ...

随机推荐

  1. JavaScript要点 (一) 变量-作用域

    JavaScript 作用域 作用域—可访问变量的集合. 全局变量或者函数可以覆盖window对象的变量或者函数: 局部变量和window对象可以覆盖全局变量和函数. JavaScript 作用域 在 ...

  2. HDU4279(2012年天津网络赛---数论分析题)

    题目:Number 题意: 给出一个f(x),表示不大于x的正整数里,不整除x且跟x有大于1的公约数的数的个数.定义F(x),为不大于x的正整数里,满足f(x)的值为奇数的数的个数.题目就是求这个F( ...

  3. 【转】使用junit4进行单元测试(高级篇)

    转自:http://blog.csdn.net/andycpp/article/details/1329218 通过前 2 篇文章,您一定对 JUnit 有了一个基本的了解,下面我们来探讨一下JUni ...

  4. 2014-2015 ACM-ICPC, Asia Xian Regional Contest G The Problem to Slow Down You 回文树

    The Problem to Slow Down You Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjud ...

  5. Andropid自己定义组件-坐标具体解释

    在做一个view背景特效的时候被坐标的各个获取方法搞晕了,几篇抄来抄去的博客也没弄非常清楚. 如今把整个总结一下. 事实上仅仅要把以下这张图看明确就没问题了. watermark/2/text/aHR ...

  6. careercup-C和C++ 13.5

    13.5 谈谈C语言关键字”volatile”的意义(或重要性)? 解答 关键字volatile的作用是指示编译器,即使代码不对变量做任何改动,该变量的值仍可能被外界修改.操作系统.硬件或其他线程都可 ...

  7. 文件和目录之utime函数

    一个文件的访问和修改时间可以用utime函数更改. #include <utime.h> int utime( const char *pathname, const struct uti ...

  8. View绘制详解(二),从setContentView谈起

    掐指一算,本来今天该介绍View的测量了,可是要说View的测量,那就要从setContentView谈起了,setContentView本身涉及到的东西也是挺多的,所以今天我们就先来看看这个setC ...

  9. java基础学习总结六(对象与类、类的属性与方法)

    一:面向过程与面向对象的区别 举例:一个人开门的动作,可以分解为开门,人进去,关门. 面向过程:人作为执行者,1:开门  2:进入   3:关门 面向对象:人作为指挥者,将开门,关门的动作都封装到门上 ...

  10. Objec类和final关键字的用法

    一.在继承中,子类继承父类,那父类继承谁呢,java中如果类没有指定继承谁,那么就默认继承Object类,object类是所有对象的直接或者间接的父类,根类,或者叫做基类,它里面定义的功能所有的对象都 ...