需求:

三个线程,依次打印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. jquery常用事件——幕布

    jquery常用事件:https://mubu.com/doc/yIEfCgCxy0

  2. linux下用rpm 安装jdk

    转载自http://blog.csdn.net/ldl22847/article/details/7605650 1.下载jdk的rpm安装包,这里以jdk-7u4-linux-i586.rpm为例进 ...

  3. 获取表单提交的数据getParameter()方法

    请求对象:request public String getParameter(String name); 通过request的getParameter(String name)方法获取 表单里面的n ...

  4. 老男孩Day16作业:登录、注册、后台管理页面(动态)

    一.作业需求: 1.后台管理主界面(左边菜单框.(全选.反选)框.返回顶部按钮) 2.老男孩登录.注册页面 二.博客地址:https://www.cnblogs.com/catepython/p/93 ...

  5. SDUT OJ 顺序表应用2:多余元素删除之建表算法

    顺序表应用2:多余元素删除之建表算法 Time Limit: 3 ms Memory Limit: 600 KiB Submit Statistic Discuss Problem Descripti ...

  6. 关于Execel 2007 连接到 hive odbc

    官方给出的都是 2010 或2012版的连接方案,看起来与2007有些不同,但我相信这些功能都是通用的. 下载 odbc hive 驱动.http://hortonworks.com/products ...

  7. 【问题记录】在执行js的时候报错:missing ) after argument list

    在执行个js语句时候报错: 报错语句: js('document.querySelector("[class] [tabindex='0']:nth-child(2) span") ...

  8. 洛谷 P1217 [USACO1.5]回文质数 Prime Palindrome

    嗯... 这道题对于蒟蒻的我来说实在是TQL... 先看一下题:(题目链接:https://www.luogu.org/problemnew/show/P1217) 然后说一下我的做题过程吧: 一看到 ...

  9. mysql 导入 导出

    mysql导入导出sql文件   window下 1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u dbuser -p dbname ...

  10. C++_IO与文件5-文件的输入与输出

    大多数计算机程序都使用了文件.文件本身是存储在某种设备上的一系列字节. 通常,操作系统管理文件,跟踪它们的位置.大小.创建时间等. 除非在操作系统级别上编程,否则通常不必担心这些事情. 真正需要的是将 ...