Java线程同步打印ABC
需求:
三个线程,依次打印ABCABCABC....
方案一:
使用阻塞队列,线程1从队列1获取内容打印,线程2从队列2获取内容打印,线程3从队列3中获取内容打印。线程1把B放到队列3中,线程2把C放到队列3中,线程3把A放到队列1中。
demo:
demo里面防止打印太快,使用了Thread.sleep(1000),以及原子变量,记录打印次数。
PrintTask.java
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger; /**
* Created by GuanXF on 2017/12/8.
*/
public class PrintTask {
private static BlockingQueue<Character>[] blockingQueues = new BlockingQueue[]{new LinkedBlockingQueue(),new LinkedBlockingQueue(), new LinkedBlockingQueue()};
private static AtomicInteger printCount = new AtomicInteger(0); public static void main(String[] args) {
Thread t1 = new Thread(new PrintA());
Thread t2 = new Thread(new PrintB());
Thread t3 = new Thread(new PrintC());
t1.start();
t2.start();
t3.start();
} static class PrintA implements Runnable{ public void run() {
while(true){
try {
System.out.println(blockingQueues[0].take());
blockingQueues[1].put('B');
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
} static class PrintB implements Runnable{ public void run() {
while(true){
try {
System.out.println(blockingQueues[1].take());
blockingQueues[2].put('C');
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
} static class PrintC implements Runnable{ public void run() {
while(true){
try {
blockingQueues[0].put('A');
System.out.println(blockingQueues[2].take());
System.out.println("----------------" + printCount.incrementAndGet() + "------------------");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}
}
方案二:
使用整型变量记录那个值该哪个线程打印,比如 state % 3 == 0线程1打印A,state % 3 == 0线程2打印B,state % 3 == 0线程3打印C
demo
PrintTaskUseState.java
import java.util.concurrent.atomic.AtomicInteger; /**
* Created by GuanXF on 2017/12/8.
*/
public class PrintTaskUseState {
private static AtomicInteger state = new AtomicInteger(0);
private static AtomicInteger printCount = new AtomicInteger(0); public static void main(String[] args) {
Thread t1 = new Thread(new PrintA(), "---PrintA----");
Thread t2 = new Thread(new PrintB(), "---PrintB----");
Thread t3 = new Thread(new PrintC(), "---PrintC----");
t1.start();
t2.start();
t3.start();
} static class PrintA implements Runnable{ public void run() {
while(true){
if(state.get() % 3 == 0){
System.out.println('A');
state.getAndIncrement();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} static class PrintB implements Runnable{ public void run() {
while(true){
if(state.get() % 3 == 1){
System.out.println('B');
state.getAndIncrement();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
} static class PrintC implements Runnable{ public void run() {
while(true){
if(state.get() % 3 == 2){
System.out.println('C');
state.set(0);
System.out.println("----------------" + printCount.incrementAndGet() + "------------------");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
备注,在第二个demo使用了命名线程,可以使用jstack -l pid把进程dump下来,看到每个线程的状态,比如阻塞等。这是一个很好的方法。
Java线程同步打印ABC的更多相关文章
- Java多线程循环打印ABC的5种实现方法
https://blog.csdn.net/weixin_39723337/article/details/80352783 题目:3个线程循环打印ABC,其中A打印3次,B打印2次,C打印1次,循环 ...
- java 线程同步 原理 sleep和wait区别
java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...
- Java线程同步_1
Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...
- Java线程同步之一--AQS
Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...
- java线程 同步临界区:thinking in java4 21.3.5
java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...
- JAVA - 线程同步和线程调度的相关方法
JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...
- Java线程同步的四种方式详解(建议收藏)
Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...
- Java线程同步和线程通信
一.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步. 不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全. 1.同步 ...
- 【总结】Java线程同步机制深刻阐述
原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...
随机推荐
- 自动判断PC端、手机端跳往不同的域名JS实现代码
输入相同域名,在pc端和移动端会出现不同的页面效果,一种是用栅格系统实现自适应, 更多的是设计两套不同的模板和两个二级域名或者一个主域名和一个二级域名(就是有区别就可以了); js代码判断浏览器的用户 ...
- [HNOI/AHOI2018]排列
[Luogu4437] 如果\(a[i]=j\)则序列\(p[]\)中\(j\)必须排在\(i\)前面,如果\(j\)不在范围内则不管,求一个式子\(\sum_{i=1}^n iw_{p[i]}\)的 ...
- sharepoint_study_3
SharePoint网页无法打开 描述:安装部署好SharePoint开发环境后,再修改计算机的机器名,重启计算机后,发现SharePoint网站不能打开. 解决:1.将机器名改回去,重启计算机,问题 ...
- codeforces 1072D Minimum path bfs+剪枝 好题
题目传送门 题目大意: 给出一幅n*n的字符,从1,1位置走到n,n,会得到一个字符串,你有k次机会改变某一个字符(变成a),求字典序最小的路径. 题解: (先吐槽一句,cf 标签是dfs题????) ...
- npm install时 报错Maximum call stack size exceeded
给npm降级或者升级 降级 : npm install -g npm@5.4.0 升级 : npm install -g npm 升级到最新版
- ul模拟select,位置,数据,是否可输入及输入提示效果都可作为参数直接传入
转发请注明出处,虽然转发几率不大... HTML <span class="theContainer"></span> CSS body {padding: ...
- UESTC - 1610 递推方程+矩阵快速幂
感觉像是HDU Keyboard的加强版,先推出3张牌时的所有组合,然后递推出n张牌 看到n=1e18时吓尿了 最后24那里还是推错了.. (5行1列 dp[1][n],dp[2][n],dp[3][ ...
- [转] 浏览器自动化测试初探:使用 phantomjs 与 casperjs
[From] https://www.qcloud.com/community/article/641602001489391648 作者:yangchunwen 首先要解释一下为什么叫浏览器自动化测 ...
- python3.6从含有html代码的json的中取出某个值
python3.6从含有html代码的json的中取出某个值 之前在做接口测试的时候,网站的后端是用java写的,然后接口的response返回的都是json格式,json很简单,就是字典,类似这样子 ...
- 转 C#对多个集合和数组的操作(合并,去重,判断)
在开发过程中.数组和集合的处理是最让我们担心.一般会用for or foreach 来处理一些操作.这里介绍一些常用的集合跟数组的操作函数. 首先举例2个集合A,B. List<int> ...