迅雷笔试题:

编写一个程序,开启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. 【转】解决HttpServletResponse输出的中文乱码问题

    http://blog.csdn.net/simon_1/article/details/9092747 首先,response返回有两种,一种是字节流outputstream,一种是字符流print ...

  2. URL是否有效

    unit Unit1;interfaceuses    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...

  3. CPU相关信息

    unit untCpuInfo;interface{ 获取 CPU 制造商 }function GetCpuFactory: String;{ 获取 CPU 家族系统 }function GetCpu ...

  4. iOS开发——Swift篇&单例的实现

    Swift实现单例模式 Swift实现单例模式 由于Swift语言弱化了struct和class之间的界限,这里我分别给出自己写的两种的单例实现 class版本: class SwiftSinglet ...

  5. js jquery 等的地址

    jquery在线地址(jquery地址):http://code.jquery.com/jquery-latest.js js人脉图(关系图)插件: http://js.cytoscape.org/

  6. javascript中window.event事件用法详解

    转自http://www.jb51.net/article/32564.htm描述 event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等. event对象只在事件发生 ...

  7. 第二次作业第2题_JH

    2.每人自己建立一个HelloWorld项目,练习使用git的add/commit/push/pull/fetch/clone等基本命令.比较项目的新旧版本的差别. (1)创建一个HelloWorld ...

  8. 阅读《RobHess的SIFT源码分析:综述》笔记

    今天总算是机缘巧合的找到了照样一篇纲要性质的文章. 如是能早一些找到就好了.不过“在你认为为时已晚的时候,其实还为时未晚”倒是也能聊以自慰,不过不能经常这样迷惑自己,毕竟我需要开始跑了! 就照着这个大 ...

  9. java基础学习总结五(递归算法、冒泡排序、查看生成API)

    一:递归算法 概念:自己调用自己的方法 示例代码如下: @Test /** * 递归求和 * 5+4+3+2+1=15 */ public void getSum() { long sum = sum ...

  10. 关于JFace的自定义对话框(Dialog类)

    仅仅是使用MessageDialog,InputDialog等JFace中现成的对话框类是无法满足实际项目开发需要的. 很多时候都需要自己定制对话框,自定义对话框只要在Dialog类的基础上作扩展就行 ...