需求:

三个线程,依次打印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的更多相关文章

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

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

  2. java 线程同步 原理 sleep和wait区别

    java线程同步的原理java会为每个Object对象分配一个monitor, 当某个对象(实例)的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处 ...

  3. Java线程同步_1

    Java线程同步_1 synchronized 该同步机制的的核心是同步监视器,任何对象都可以作为同步监视器,代码执行结束,或者程序调用了同步监视器的wait方法会导致释放同步监视器 synchron ...

  4. Java线程同步之一--AQS

    Java线程同步之一--AQS 线程同步是指两个并发执行的线程在同一时间不同时执行某一部分的程序.同步问题在生活中也很常见,就比如在麦当劳点餐,假设只有一个服务员能够提供点餐服务.每个服务员在同一时刻 ...

  5. java线程 同步临界区:thinking in java4 21.3.5

    java线程 同步临界区:thinking in java4 21.3.5 thinking in java 4免费下载:http://download.csdn.net/detail/liangru ...

  6. JAVA - 线程同步和线程调度的相关方法

    JAVA - 线程同步和线程调度的相关方法 wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁:wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等 ...

  7. Java线程同步的四种方式详解(建议收藏)

    ​ Java线程同步属于Java多线程与并发编程的核心点,需要重点掌握,下面我就来详解Java线程同步的4种主要的实现方式@mikechen 目录 什么是线程同步 线程同步的几种方式 1.使用sync ...

  8. Java线程同步和线程通信

    一.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步. 不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全. 1.同步 ...

  9. 【总结】Java线程同步机制深刻阐述

    原文:http://hxraid.iteye.com/blog/667437 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread ...

随机推荐

  1. Python3之时间模块time & datetime & calendar

    一. 简介 python 提供很多方式处理日期与时间,转换日期格式是一个常见的功能. 时间元组:很多python函数用一个元组装起来的9组数字处理时间. python中时间日期格式化符号: %y 两位 ...

  2. controller运行springboot项目

    搭建完springboot项目后,新建HelloController.java文件,编写main方法,启动HelloController.java,具体代码如图: 在浏览器访问127.0.0.1:80 ...

  3. VUE学习(一)

    1.搭建vue环境 2.了解 v-on  事件监听,常常跟事件(click,mousemove,change等鼠标或者手势事件)在一起,eg:v-on:click,语法糖——:(冒号) 需要在meth ...

  4. SQL SERVER下有序GUID和无序GUID作为主键&聚集索引的性能表现

     背景 前段时间学习<Microsoft SQL Server 2008技术内幕:T-SQL查询>时,看到里面关于无序GUID作为主键与聚集索引的建议,无序GUID作为主键以及作为聚集索引 ...

  5. sharding-jdbc springboot配置

    SPRING BOOT配置 注意事项 行表达式标识符可以使用${...}或$->{...},但前者与Spring本身的属性文件占位符冲突,因此在Spring环境中使用行表达式标识符建议使用$-& ...

  6. Hibernate学习笔记(五)—— Hibernate查询方式

    一.对象图导航查询 对象图导航查询方式是根据已经加载的对象,导航到他的关联对象.它利用类与类之间的关系来查询对象.比如要查找一个联系人对应的客户,就可以由联系人对象自动导航找到联系人所属的客户对象.当 ...

  7. [HAOI2015]按位或(FWT)

    [Luogu3175] [BZOJ4036] [DarkBZOJ没有spj] 原理-shadowice 本题题解 我们要求的,实际上是一个集合\(n\)个\(1\)中最晚出现的\(1\)的期望时间 显 ...

  8. 文献综述三:基于JSP的商品信息管理系统设计与开发

    一.基本信息 标题:基于JSP的商品信息管理系统设计与开发 时间:2015 出版源:Computer Knowledge and Technology 文件分类:jsp技术的系统开发 二.研究背景 通 ...

  9. nginx优化项目

    隐藏版本信息 server_tokensSyntax:     server_tokens on | off | build | string;Default:     server_tokens o ...

  10. AutoFac之 Named and Keyed 方式注入

    AutoFac是.net framework下一个高效的ioc容器,传说中的效率最快(我偷偷看了几篇测试博文,确实这个容器的效率遥遥领先). 好了废话不多说,AutoFac的使用方式请看:http:/ ...