一、需求
- A、B、C 三个线程,循环10次,打印出自己的名称,ABC,ABC,ABC...
- A、B、C 三个线程,循环10次,打印出自己的名称,A一次,B三次,C五次,ABBBCCCCC,ABBBCCCCC
1.1、循环打印ABC
package com.example.demo.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author DUCHONG
* @since 2019-01-21 10:46
**/
public class ABC {
public static void main(String[] args) {
PrintDemo pd=new PrintDemo();
//A 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printA(i);
}
}
},"A").start();
//B 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printB(i);
}
}
},"B").start();
//C 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printC(i);
}
}
},"C").start();
}
}
class PrintDemo{
Lock lock =new ReentrantLock();
private Condition conditionA=lock.newCondition();
private Condition conditionB=lock.newCondition();
private Condition conditionC=lock.newCondition();
//哪个线程等待与否的标记,flag的值:
// 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
// 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
// 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A 外层一次循环结束。
private Integer flag=1;
//打印A
public void printA(int loop){
try{
lock.lock();
if(flag!=1){
conditionA.await();
}
for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=2;
conditionB.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
//打印B
public void printB(int loop){
try{
lock.lock();
if(flag!=2){
conditionB.await();
}
for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=3;
conditionC.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
//打印C
public void printC(int loop){
try{
lock.lock();
if(flag!=3){
conditionC.await();
}
for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=1;
conditionA.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
}
结果:
1.2、循环打印ABBBCCCC
package com.example.demo.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author DUCHONG
* @since 2019-01-21 14:15
**/
public class ABBB {
public static void main(String[] args) {
PrintABBBDemo pd=new PrintABBBDemo();
//A 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printA(i);
}
}
},"A").start();
//B 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printB(i);
}
}
},"B").start();
//C 线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <=10 ; i++) {
pd.printC(i);
}
}
},"C").start();
}
}
class PrintABBBDemo{
Lock lock =new ReentrantLock();
private Condition conditionA=lock.newCondition();
private Condition conditionB=lock.newCondition();
private Condition conditionC=lock.newCondition();
//哪个线程等待与否的标记,flag的值:
// 1 线程A打印,否则等待,同时将标记设置为2,唤醒线程B
// 2 线程B打印,否则等待,同时将标记设置为3,唤醒线程C
// 3 线程C打印,否则等待,同时将标记设置为1,唤醒线程A 外层一次循环结束。
private Integer flag=1;
//打印A
public void printA(int loop){
try{
lock.lock();
if(flag!=1){
conditionA.await();
}
for (int i=1;i<=1;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=2;
conditionB.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
//打印B
public void printB(int loop){
try{
lock.lock();
if(flag!=2){
conditionB.await();
}
for (int i=1;i<=3;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=3;
conditionC.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
//打印C
public void printC(int loop){
try{
lock.lock();
if(flag!=3){
conditionC.await();
}
for (int i=1;i<=5;i++) {
System.out.println(Thread.currentThread().getName() + "---" + loop);
}
flag=1;
conditionA.signal();
}
catch(Exception e){
e.printStackTrace();
}
finally {
lock.unlock();
}
}
}
结果: