用三个线程循环输出ABC
前两天看Java吧有人求助这个问题。想了想并不是很难。今天就顺手实现了一下。
我自己想到的有两种方法,一个是使用synchronized,一个是使用lock。
一、synchronized
package com.test;
public class PrintABC {
private static int count = 0;
public static void main(String[] args) {
String str = "ABC";
PrintABC printABC = new PrintABC();
ThreadA threadA = printABC.new ThreadA(str);
ThreadB threadB = printABC.new ThreadB(str);
ThreadC threadC = printABC.new ThreadC(str);
threadA.start();
threadB.start();
threadC.start();
}
/**
* 打印A
* @author LKB
*
*/
class ThreadA extends Thread{
private String str;
public ThreadA(String str) {
// TODO Auto-generated constructor stub
this.str = str;
}
public void run(){
while(count < 28){
synchronized (str) {
if(count%3 == 0){
System.out.println("A");
count++;
}
}
}
}
}
/**
* 打印B
* @author LKB
*
*/
class ThreadB extends Thread{
private String str;
public ThreadB(String str) {
// TODO Auto-generated constructor stub
this.str = str;
}
public void run(){
while(count < 29){
synchronized (str) {
if(count%3 == 1){
System.out.println("B");
count++;
}
}
}
}
}
/**
* 打印C
* @author LKB
*
*/
class ThreadC extends Thread{
private String str;
public ThreadC(String str) {
// TODO Auto-generated constructor stub
this.str = str;
}
public void run(){
while(count < 30){
synchronized (str) {
if(count%3 == 2){
System.out.println("C");
System.out.println("++++++");
System.out.println("------");
count++;
}
}
}
}
}
}
这个方法的关键是synchronized关键字的位置。把它放在while判断之下就OK了。如果把synchronized关键字放在while外,则一直在锁中无法跳出锁。
二、lock
package com.test; import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class PrintABC2 { private int count = 0;
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition(); public static void main(String[] args) {
PrintABC2 printABC = new PrintABC2();
ThreadA threadA = printABC.new ThreadA();
ThreadB threadB = printABC.new ThreadB();
ThreadC threadC = printABC.new ThreadC();
threadA.start();
threadB.start();
threadC.start(); } /**
* 打印A
* @author LKB
*
*/
class ThreadA extends Thread{ public void run(){
try {
lock.lock();
while(count < 30){
if (count%3 != 0) {
conditionA.await();
}
System.out.println("A");
count ++;
conditionB.signalAll();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.unlock();
System.out.println("ThreadA 中执行了 unlock");
}
}
} /**
* 打印B
* @author LKB
*
*/
class ThreadB extends Thread{ public void run(){
try {
lock.lock();
while(count < 30){
if (count%3 != 1) {
conditionB.await();
}
System.out.println("B");
count ++;
conditionC.signalAll();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.unlock();
System.out.println("ThreadB 中执行了 unlock");
}
}
} /**
* 打印C
* @author LKB
*
*/
class ThreadC extends Thread{ public void run(){
try {
lock.lock();
while(count < 30){
if (count%3 != 2) {
conditionC.await();
}
System.out.println("C");
System.out.println("+++++++");
System.out.println("-------");
count ++;
if(count < 30){
conditionA.signalAll();
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.unlock();
System.out.println("ThreadC 中执行了 unlock");
}
}
} }
lock方法相对而言就简单多了,不需要精妙地设计,只需要知道lock和condition的用法就好了。
在一个lock对象里可以创建多个Condition(即对象监视器)实例。线程对象可以注册到指定的Condition中,从而可以有选择性地进行线程通知。
用三个线程循环输出ABC的更多相关文章
- 使用Java 多线程编程 让三个线程轮流输出ABC,循环10次后结束
简要分析: 要求三个线程轮流输出,这里我们要使用一个对象锁,让关键部分的代码放入同步块当中.同时要有一个变量记录打印的次数到达10次循环后不再打印,另外一个就是要给每个线程一个标志号,我们根据标识号来 ...
- java Semaphore实现ABC三个线程循环打印
Semaphore位于java.util.concurrent包下.其中有两个重要的方法acquire()和release().acquire用来获取一个信号量,并且是阻塞型的,如果当前还有可用的信号 ...
- Java多线程:用三个线程控制循环输出10次ABC
转载:http://www.cnblogs.com/gaopeng527/p/5257884.html 题目:有A,B,C三个线程, A线程输出A, B线程输出B, C线程输出C,要求, 同时启动三个 ...
- Java多线程循环打印ABC的5种实现方法
https://blog.csdn.net/weixin_39723337/article/details/80352783 题目:3个线程循环打印ABC,其中A打印3次,B打印2次,C打印1次,循环 ...
- java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现
注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...
- java中使用ReentrantLock锁中的Condition实现三个线程之间通信,交替输出信息
本文直接附上源代码,如下是自己写的一个例子 面试题需求: 使用Condition来实现 三个线程 线程1 线程2 线程3 三个交替输出 [按照 线程1(main)-->线程2-->线程3] ...
- C#中添加三个线程同时启动执行某一方法,并依次调用某方法中的循环打印输。
添加三个线程同时启动执行某一方法,并依次调用某方法中的打印输:ABC ABC ABC ABC 实现代码如下: using System; using System.Collections.Generi ...
- 斐讯面试记录—三线程交替打印ABC
package cn.shenzhen.feixun; public class PrintABC extends Thread{ private String name; private Objec ...
- 三个线程abc顺序执行
1.使用synchronized悲观锁(秋招阿里的一个笔试题,应该写的比较复杂,然后就没有然后了o(╥﹏╥)o) public class ThreadThreadp { private int fl ...
随机推荐
- Spring整合JMS(四)——事务管理(转)
*注:别人那复制来的 Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.Jm ...
- 【Android】完善Android学习(七:API 4.0.3)
备注:之前Android入门学习的书籍使用的是杨丰盛的<Android应用开发揭秘>,这本书是基于Android 2.2API的,目前Android已经到4.4了,更新了很多的API,也增 ...
- 解决VSCode终端中文乱码问题
VSCode终端其实调用的是cmd.exe,所以当这里出现中文乱码的时候要解决的是cmd的编码设置问题. 可以通过chcp命令查看cmd的编码设置,GBK2312的代码页编号是936,然后改成utf- ...
- SPOJ DQUERY 离线树状数组+离散化
LINK 题意:给出$(n <= 30000)$个数,$q <= 2e5$个查询,每个查询要求给出$[l,r]$内不同元素的个数 思路:这题可用主席树查询历史版本的方法做,感觉这个比较容易 ...
- KMP next表模板
void makeNext(const char P[],int next[]) { int q,k;//q:模版字符串下标:k:最大前后缀长度 int m = strlen(P);//模版字符串长度 ...
- Spring REST 异常处理
在上一篇中写到了Spring MVC的异常处理,SpringMVC捕获到异常之后会转到相应的错误页面,但是我们REST API ,一般只返回结果和状态码,比如发生异常,只向客户端返回一个500的状态码 ...
- (64位)本体学习程序(ontoEnrich)系统配置说明文档
1系统环境 64位 Ubuntu 2 第三方依赖库配置 boost_1_44_0 #解压boost_1_44_0.tar.gz 到 /usr/local.如果出现权限问题,请用sudo执行该命令 ta ...
- Lua只读表
利用Lua的元表(metatable)和元函数(metafunction)可以很简单的实现此功能. 其实现大致分为三个部分 1.禁止在表中创建新值 2.禁止改变已有的值 3.将子表也变为只读 1.禁止 ...
- 【BZOJ】2599: [IOI2011]Race 点分治
[题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...
- 【BZOJ】3572: [Hnoi2014]世界树 虚树+倍增
[题意]给定n个点的树,m次询问,每次给定ki个特殊点,一个点会被最近的特殊点控制,询问每个特殊点控制多少点.n,m,Σki<=300000. [算法]虚树+倍增 [题解]★参考:thy_asd ...