需求:

三个线程,依次打印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. 【AOP】基于@Aspect的AOP配置

    基于spring cloud的aop配置 1,启动类MemberAppliaction增加注解 @Import({SwaggerConfiguraion.class, WebMvcAutoConfig ...

  2. Python之路Python作用域、匿名函数、函数式编程、map函数、filter函数、reduce函数

    Python之路Python作用域.匿名函数.函数式编程.map函数.filter函数.reduce函数 一.作用域 return 可以返回任意值例子 def test1(): print(" ...

  3. 17、OpenCV Python 数字验证码识别

    __author__ = "WSX" import cv2 as cv import numpy as np from PIL import Image import pytess ...

  4. JS 创建元素的三种方法

    1.动态创建元素一 document.write() 例如向页面中输出一个 li 标签 <pre class="html" name="code"> ...

  5. ubuntu下QtCreator启动无响应问题解决

    打开Qt后就卡死. 解决方法:删除系统配置目录下的QtProject文件夹: find / -name QtProject 输出: /root/.config/QtProject 删除QtProjec ...

  6. 4A - Horse

    打表找规律 #include <iostream> #include <queue> using namespace std; ][]; ]{, , , , -, -, -, ...

  7. 移动端适配1px问题

    (function(document) { var dcl = document.documentElement, wh; var scale = 1/window.devicePixelRatio; ...

  8. Javascript 中 的坑..

    ### 1. 0 == '' 返回 true 0 === '' 返回false......... 切记...

  9. PHP中Session ID的实现原理

    前序: 首先要明白PHPSESSID看似多次刷新都不会改变其实是没有删除本地相关联的cookie,删除的方法 session_destroy();//删除服务器端的session文件 setcooki ...

  10. m3m4加载器的优化版m3m4-v1.1

    m3m4加载器的优化版m3m4-v1.1 /* //1.以$开头的模块名,表示服务,服务只会执行一次,它可以有自己的方法.比如cookie就是一个服务 //例如:console.log("r ...