[******] java多线程连续打印abc
题目描述
建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印。
5种方法
- 使用synchronized, wait和notifyAll
- 使用Lock->ReentrantLock 和 state标志
- 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)
- 使用Semaphore
- 使用AtomicInteger
- 扩展:采用join实现(一次性打印)
5.1 使用synchronized, wait和notifyAll
public class ABC7 {
private static Object o = new Object();//所对象
private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量 static class ThreadGenetic implements Runnable {
char name;
int data;
public ThreadGenetic(char name, int data){
this.name = name;
this.data = data;
}
public void run() {
synchronized (o) {
for(int i = 0; i < PRINT_NUMBER; ) {
if(state % THREAD_NUM == data){//保证顺序
System.out.print(name);
++ state;
i++;//注意保证迭代次数
o.notifyAll();
}else{
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
} public static void main(String[] args) {
new Thread(new ThreadGenetic('B',1)).start();
new Thread(new ThreadGenetic('A',0)).start();
new Thread(new ThreadGenetic('C',2)).start(); } }
5.2 使用Lock->ReentrantLock 和 state标志
import java.util.concurrent.locks.ReentrantLock; public class ABC {
private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁 static class ThreadGenetic extends Thread{
char name;
int data;
public ThreadGenetic(char name, int data){
this.name = name;
this.data = data;
}
public void run(){
for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
lock.lock();
if(state % THREAD_NUM == this.data){//确保按顺序打印
System.out.print(this.name);
state++; //确保按顺序打印
i++; //确保打印次数
}
lock.unlock();
}
}
} public static void main(String[] args) {
new ThreadGenetic('B',1).start();
new ThreadGenetic('C',2).start();
new ThreadGenetic('A',0).start();
}
}
5.3 使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)
方法1
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class ABC8 {
private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁
private static Condition condition = lock.newCondition(); static class ThreadGenetic extends Thread{
char name;
int data;
public ThreadGenetic(char name, int data){
this.name = name;
this.data = data;
}
public void run(){
lock.lock();
try {
for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
while(state % THREAD_NUM != data){//确保按顺序打印
condition.await();
}
System.out.print(name);
state++; //确保按顺序打印
i++; //确保打印次数
condition.signalAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
} public static void main(String[] args) {
new ThreadGenetic('B',1).start();
new ThreadGenetic('C',2).start();
new ThreadGenetic('A',0).start();
}
}
方法2
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock; public class ABC2 {
private static int state = 0;//控制顺序
private static int PRINT_NUMBER = 10;//打印次数
private static int THREAD_NUM = 3;//线程数量
private static ReentrantLock lock = new ReentrantLock();//锁
private static Condition conditionA = lock.newCondition();
private static Condition conditionB = lock.newCondition();
private static Condition conditionC = lock.newCondition(); static class ThreadGenetic extends Thread{
char name;
int data;
Condition condition1;
Condition condition2;
public ThreadGenetic(char name, int data, Condition condition1,Condition condition2){
this.name = name;
this.data = data;
this.condition1 = condition1;
this.condition2 = condition2;
}
public void run(){
lock.lock();
try {
for (int i = 0; i < PRINT_NUMBER; ) {//确保打印次数
while(state % THREAD_NUM != data){//确保按顺序打印
condition1.await();
}
System.out.print(name);
state++; //确保按顺序打印
i++; //确保打印次数
condition2.signal();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
} public static void main(String[] args) {
new ThreadGenetic('B',1,conditionB,conditionC).start();
new ThreadGenetic('C',2,conditionC,conditionA).start();
new ThreadGenetic('A',0,conditionA,conditionB).start();
}
}
5.4 使用Semaphore
import java.util.concurrent.Semaphore; public class ABC3 {
private static int PRINT_NUMBER = 10;//打印次数
private static Semaphore semaphoreA = new Semaphore(1);
private static Semaphore semaphoreB = new Semaphore(1);
private static Semaphore semaphoreC = new Semaphore(1); static class ThreadGenetic extends Thread{
char name;
int data;
Semaphore semaphore1;
Semaphore semaphore2;
public ThreadGenetic(char name, Semaphore semaphore1,Semaphore semaphore2){
this.name = name;
this.semaphore1 = semaphore1;
this.semaphore2 = semaphore2;
}
public void run(){
for (int i = 0; i < PRINT_NUMBER; i++) {//确保打印次数
try {
semaphore1.acquire();
System.out.print(name);
semaphore2.release();
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
}
public static void main(String[] args) {
try {
semaphoreB.acquire();//保证A先于BC开始
semaphoreC.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
new ThreadGenetic('B',semaphoreB,semaphoreC).start();
new ThreadGenetic('C',semaphoreC,semaphoreA).start();
new ThreadGenetic('A',semaphoreA,semaphoreB).start();
}
}
5.5 使用AtomicInteger
import java.util.concurrent.atomic.AtomicInteger; public class ABC5 {
private static AtomicInteger atomicinteger = new AtomicInteger(0);
private static final int MAX_SYC_VALUE = 3 * 10; static class ThreadGenetic extends Thread {
char name;
int data; public ThreadGenetic(char name, int data) {
this.name = name;
this.data = data;
} public void run() {
while (atomicinteger.get() < MAX_SYC_VALUE-1) {
if (atomicinteger.get() % 3 == data) {
System.out.print(name);
atomicinteger.getAndIncrement();
}
} }
} public static void main(String[] args) {
new ThreadGenetic('B', 1).start();
new ThreadGenetic('C', 2).start();
new ThreadGenetic('A', 0).start();
}
}
5.6 采用join实现(一次性打印)
public class ABC6 { public static void main(String[] args) {
// 线程A
final Thread a = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("A");
}
}); // 线程B
final Thread b = new Thread(new Runnable() {
@Override
public void run() {
try {
// 执行b线程之前,加入a线程,让a线程执行
a.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B");
}
}); // 线程C
final Thread c = new Thread(new Runnable() {
@Override
public void run() {
try {
// 执行c线程之前,加入b线程,让b线程执行
b.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("C");
}
}); // 启动三个线程
a.start();
b.start();
c.start();
}
}
[******] java多线程连续打印abc的更多相关文章
- java多线程编程题之连续打印abc的几种解法
一道编程题如下: 实例化三个线程,一个线程打印a,一个打印b,一个打印c,三个线程同时执行,要求打印出6个连着的abc 题目分析: 通过题意我们可以得出,本题需要我们使用三个线程,三个线程分别会打印6 ...
- java多线程编程之连续打印abc的几种解法
一道编程题如下: 实例化三个线程,一个线程打印a,一个线程打印b,一个线程打印c,三个线程同时执行,要求打印出10个连着的abc. 题目分析: 通过题意我们可以得出,本题需要我们使用三个线程,三个线程 ...
- 三线程连续打印ABC
package test5; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Reentr ...
- Java多线程学习(转载)
Java多线程学习(转载) 时间:2015-03-14 13:53:14 阅读:137413 评论:4 收藏:3 [点我收藏+] 转载 :http://blog ...
- 转:关于JAVA多线程同步
转:http://lanvis.blog.163.com/blog/static/26982162009798422547/ 因为需要,最近关注了一下JAVA多线程同步问题.JAVA多线程同步主要依赖 ...
- Java多线程——<一>概述、定义任务
一.概述 为什么使用线程?从c开始,任何一门高级语言的默认执行顺序是“按照编写的代码的顺序执行”,日常开发过程中写的业务逻辑,但凡不涉及并发的,都是让一个任务顺序执行以确保得到想要的结果.但是,当你的 ...
- ***Java多线程发展简史
http://blog.jobbole.com/28297/ 本文来自四火的博客(@RayChase),由@_Zhijun 推荐 这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的 ...
- [转] Java多线程发展简史
这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并 ...
- java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析
java多线程系列(五)---synchronized ReentrantLock volatile Atomic 原理分析 前言:如有不正确的地方,还望指正. 目录 认识cpu.核心与线程 java ...
随机推荐
- vue数据更改视图不更新问题----深入响应式原理
Vue响应式原理之官方解释 当你把一个普通的JavaScript对象传给Vue实例的data选项,Vue将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为get ...
- DVWA-CSRF学习笔记
DVWA-CSRF学习笔记 一.CSRF(跨站请求伪造) CSRF(跨站请求伪造),是指利用受害者尚未失效的身份认证信息(cookie.session会话等),诱骗其点击恶意链接或者访问包含攻击代码的 ...
- C# 委托补充01
上一篇文章写了委托的最基本的一些东西,本篇咱们扯扯委托其他的东西. 示例1插件编程 根据对委托的理解,委托可以把一个方法当作参数进行传递,利用这个特性我们可以使用委托,实现插件编程. public d ...
- linux应用管理
desktop文件的几个位置: /usr/share/applications ~/.local/share/applications /usr/local/share/applications li ...
- vue父子组件的通信
一.父组件向子组件传递数据 1.首先形成父子组件关系 <!DOCTYPE html> <html lang="en"> <head> <m ...
- Lodash 严重安全漏洞背后 你不得不知道的 JavaScript 知识
摘要: 详解原型污染. 原文:Lodash 严重安全漏洞背后 你不得不知道的 JavaScript 知识 作者:Lucas HC Fundebug经授权转载,版权归原作者所有. 可能有信息敏感的同学已 ...
- RDD源码分析
RDD源码解析 一. RDD.scala - Resilient Distributed Dataset (RDD) 弹性分布式数据集 弹性: 体现在计算上面 - the basic abstract ...
- Lumen5.7快速实现Captcha图片验证码功能
公司发送短信注册的接口需要防刷,需要一个图形验证码,不考虑收费产品. Lumen5.7+nginx+mysql 使用了这个作者的扩展包,只讲实现.https://github.com/Youngyez ...
- Ubuntu下搭建Kubernetes集群(1)--安装docker
可以使用物理机,也可以使用虚拟机. 首先参考https://docs.docker.com/install/linux/docker-ce/ubuntu/ 官方文档学会安装docker. 1.首先移除 ...
- jmeter压测学习6-HTTP Cookie管理器
前言 web网站的请求大部分都有cookies,jmeter的HTTP Cookie管理器可以很好的管理cookies. 我用的 jmeter5.1 版本,直接加一个HTTP Cookie管理器放到请 ...