Java线程同步打印ABC
2024-10-19 21:46:48
需求:
三个线程,依次打印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下来,看到每个线程的状态,比如阻塞等。这是一个很好的方法。
最新文章
- JQuery文件上传插件ajaxFileUpload在Asp.net MVC中的使用
- GreenDao数据库框架的配置与增删改查
- UITableView增加和删除、移动
- unity HideInInspector与SerializeField
- vs2010 clickone 工程安装后的路径 win7
- Effective_java之二:慎用重载函数
- go can&#39;t find import: ";github.com/** 错误
- 从零开始学JAVA(03)-用Eclipse生成HelloWorld的Jar文件(简单不带包)
- Javascript继承实现
- Objective-C 学习笔记(Day 2)
- 每日一算法【one】
- EF数据建模(一)
- C中程序的内存分配
- freemarker字符串转换成日期和时间(十三)
- HMAC
- Python3字符串替换replace(),translate(),re.sub()
- 【Diary】
- [C++]Qt 如何处理密集型耗时的事情(频繁调用QApplication::processEvents)
- Hbase:原理和设计
- neo4j 学习-2
热门文章
- python中xml解析
- Flink应用场景
- Jenkins持续集成企业实战系列之Jenkins手动构建-----04
- Anya and Cubes 搜索+map映射
- nginx关闭默认站点/空主机头(禁止IP直接访问、防止域名恶意解析)
- Hibernate学习笔记(三)—— Hibernate的事务控制
- ZOJ Monthly, January 2019 Little Sub and his Geometry Problem ZOJ4082(模拟 乱搞)
- LightOJ - 1197 素数筛
- Spring 配置 Apache Commons Logging
- PIE SDK专题制图切换模板