[******] 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 ...
随机推荐
- Kafka关键参数设置
生产环境中使用Kafka,参数调优非常重要,而Kafka参数众多,我们的java的Configuration代码中,经常设置的参数如下: Properties props = new Properti ...
- OpenGL入门1.4:纹理/贴图Texture
每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 游戏玩家对Texture这个词应该不陌生,我们已经知道了怎么为每个顶点添加颜色来增加图形的细节,但,如果想让图形看起来更真实 ...
- WPF ItemsSource Order by Getter
public ObservableCollection<CustomerModel> CustomerCollection { get { if(customerCollection!=n ...
- webform的原生操作图片预览和上传
1.使用input标签进行图片操作,input的标签有一个accept属性,accept 属性只能与 <input type="file"> 配合使用.它规定能够通过文 ...
- mvc5 源码解析1:UrlRoutingModule
注册在C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG \webconfig中 在该module源码中 我们可以看出注册了application ...
- B-Tree详解
之前写过一篇关于索引的文章<SQL夯实基础(五):索引的数据结构>,这次我们主要详细讨论下B-Tree. B-树 B-tree,即B树,而不要读成B减树,它是一种多路搜索树(并不是二叉的) ...
- python 字符前缀,运算符、换行符、数据类型和变量
补充 *)/ 表示的除法即使是整数,结果也是浮点数 *)python表示的整数是没有大小限制的.而某些语言根据其储存长度是有大小限制的.例如Java对32位整数的范围限制在-2147483648-21 ...
- JS运算符类型
一.运算符类型 1.算术运算符: 用于各类数值运算,包括加(+).减(-).乘(*).除(/).求余(或称模运算,%).自增(++).自减(--)共七种. 2.关系运算符: 用于比较运算.包括大于(& ...
- Java面向对象——三大特性
Java面向对象——三大特性 摘要:本文主要介绍了面型对象的三大特性. 封装 什么是封装 封装,就是指一个类隐藏了对象的属性和实现细节,对自己的数据和方法进行访问权限控制,只允许某些类和对象进行访问和 ...
- 二十三:原型模式详解(clone复制方法源码)
定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 定义比较简单,总结一下是通过实例指定种类,通过拷贝创建对象. 在JAVA语言中使用原型模式是非常 ...