JAVA并发多个线程交替打印
Posted Kant101
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA并发多个线程交替打印相关的知识,希望对你有一定的参考价值。
1. 概述
多个线程交替打印是面试中最长考察JAVA并发相关的题目了,其目的在于考察对Java的J.U.C是否能熟练的使用。
例如:
1、3个线程交替打印A、B、C;
2、3个线程轮翻打印自然数;
2. 3个线程交替打印A、B、C
2.1 代码
package cn.pku.edu.algorithm.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author allen
* @date 2022/9/13
*/
public class PrintCharAlternately
public static void main(String[] args) throws InterruptedException
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
Thread threadA = new Thread(new SyncPrinter(lock, conditionA, conditionB, 'A'), "threadA");
Thread threadB = new Thread(new SyncPrinter(lock, conditionB, conditionC, 'B'), "threadB");
Thread threadC = new Thread(new SyncPrinter(lock, conditionC, conditionA, 'C'), "threadC");
threadA.start();
Thread.sleep(1000);
threadB.start();
Thread.sleep(1000);
threadC.start();
Thread.sleep(1000);
class SyncPrinter implements Runnable
// 打印次数
private static final int PRINT_COUNT = 10;
private final ReentrantLock reentrantLock;
private final Condition thisCondition;
private final Condition nextCondition;
private final char printChar;
public SyncPrinter(ReentrantLock reentrantLock, Condition thisCondition, Condition nextCondition, char printChar)
this.reentrantLock = reentrantLock;
this.thisCondition = thisCondition;
this.nextCondition = nextCondition;
this.printChar = printChar;
@Override
public void run()
// 获取打印锁,进入临界区
reentrantLock.lock();
try
// 连续打印 PRINT_COUNT 次
for (int i = 0; i < PRINT_COUNT; i++)
// 打印字符
System.out.println(Thread.currentThread().getName() + " print: " + printChar + " " + (i + 1) + " times");
// 使用nextCondition唤醒下一个线程
// 因为只有一个线程在等待,所以signal和signalAll都可以
nextCondition.signalAll();
// 不是最后一次则通过thisCondition等待被唤醒
// 必须要加判断,不然虽然能够打印10次,但是10次后就会被直接锁死
if (i < PRINT_COUNT - 1)
try
Thread.sleep(1000);
thisCondition.await();
catch (Exception e)
e.printStackTrace();
finally
reentrantLock.unlock();
2.2 测试
3. 3个线程轮翻打印自然数
3.1 代码
package cn.pku.edu.algorithm.concurrent;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author allen
* @date 2022/9/13
*/
public class PrintNumberAlternately
public static void main(String[] args)
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
Thread thread1 = new Thread(new SyncNumberPrinter(lock, conditionA, conditionB), "thread1");
Thread thread2 = new Thread(new SyncNumberPrinter(lock, conditionB, conditionC), "thread2");
Thread thread3 = new Thread(new SyncNumberPrinter(lock, conditionC, conditionA), "thread3");
thread1.start();
thread2.start();
thread3.start();
class SyncNumberPrinter implements Runnable
// 所有线程公用的数字
private static volatile int num = 0;
// 每个线程打印的次数
private final int PRINT_TIMES = 1000;
private final ReentrantLock reentrantLock;
private final Condition currentCondition;
private final Condition nextCondition;
public SyncNumberPrinter(ReentrantLock reentrantLock, Condition currentCondition, Condition nextCondition)
this.reentrantLock = reentrantLock;
this.currentCondition = currentCondition;
this.nextCondition = nextCondition;
@Override
public void run()
try
// 获取打印锁
reentrantLock.lock();
for (int i = 0; i < PRINT_TIMES; i++)
System.out.println(Thread.currentThread().getName() + " print: " + num);
num++;
Thread.sleep(1000);
// 打印完一次后,唤醒在下一个条件下等待的线程
nextCondition.signalAll();
if (i < PRINT_TIMES - 1)
// 打印完,当前线程释放锁,并等待在当前条件下,等待被别的线程唤醒
currentCondition.await();
catch (Exception e)
e.printStackTrace();
finally
// 释放打印锁
reentrantLock.unlock();
3.2 测试
4. 参考文献
以上是关于JAVA并发多个线程交替打印的主要内容,如果未能解决你的问题,请参考以下文章