原文链接:线程题大全
工作机制:初始化一个计数器,此计数器的值表示需要等待的事件数量。
提供了两个主要方法:
重要特性:
示例:在两个工作线程结束后再调用主线程
CountDownLatch latch = new CountDownLatch(2); // 设定计数器初始值为2
// 创建第一个线程,完成某项任务后调用countDown方法
new Thread(() -> {
System.out.println("线程1执行...");
latch.countDown();
System.out.println("线程1完成操作,计数器减一");
}).start();
// 创建第二个线程,也是完成某项任务后调用countDown方法
new Thread(() -> {
System.out.println("线程2执行...");
latch.countDown();
System.out.println("线程2完成操作,计数器减一");
}).start();
try {
// 调用await方法的线程会被阻塞,直到计数器的值变为0
latch.await();
System.out.println("两个线程的操作均已完成,主线程继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
工作机制:允许一组线程相互等待到达一个共同屏障点
重要特性:
示例:当四个线程都达到屏障后,打印一句话,然后每个线程继续执行它们的任务
public class CyclicBarrierExample {
// 创建一个新的CyclicBarrier,当四个参与者到达时执行屏障操作
private CyclicBarrier barrier = new CyclicBarrier(4, () -> System.out.println("所有线程到达屏障点,屏障操作执行!"));
public void startTask(String name) {
new Thread(() -> {
System.out.println(name + "开始执行任务...");
// 模拟任务耗时
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "到达屏障点,等待其他线程...");
try {
// 调用await方法等待其他线程都到达屏障点
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(name + "继续执行后续操作");
}).start();
}
public static void main(String[] args) {
CyclicBarrierExample example = new CyclicBarrierExample();
example.startTask("线程A");
example.startTask("线程B");
example.startTask("线程C");
example.startTask("线程D"); // 当所有四个线程达到屏障点,将一起释放,然后执行屏障操作
}
}
public class CrossPrinter {
private int state;
private final int printCount;
public CrossPrinter(int printCount) {
// state用来确定下次打印
this.state = 0;
// 打印次数
this.printCount = printCount;
}
public void printLetter(String Letter, int crossState ,int curState) {
for (int i = 0; i < printCount; i++) {
synchronized (this) {
while (state % crossState != curState) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ":" + Letter);
state++;
notifyAll();
}
}
}
public static void main(String[] args) {
CrossPrinter crossPrinter = new CrossPrinter(5);
// Thread A打印"A"
new Thread(() -> crossPrinter.printLetter("A", 2,0), "Thread A").start();
// Thread B打印"B"
new Thread(() -> crossPrinter.printLetter("B", 2,1), "Thread B").start();
}
}
上述完成了两线程交叉打印"A"、“B”,具体说明下
可用于:
模版中是两线程交叉打印 A、B,只需要做简单替换就能实现三线程交叉打印 A、B、C
crossState:3
新增线程 C 如下
// Thread A打印"A"
new Thread(() -> crossPrinter.printLetter("A", 3,0), "Thread A").start();
// Thread B打印"B"
new Thread(() -> crossPrinter.printLetter("B", 3,1), "Thread B").start();
// Thread C打印"C"
new Thread(() -> crossPrinter.printLetter("C", 3,2), "Thread C").start();
比如要求打印到两线程交叉打印到 10
state 控制线程进行轮次,此时可以换为 while 条件,用来控制跳出循环
crossState:2,表示两线程
完整代码如下:
public class CrossPrinter {
private int state;
private final int printCount;
public CrossPrinter(int printCount) {
// state用来确定下次打印
this.state = 0;
// printCount表示打印次数
this.printCount = printCount;
}
public void printNumber(int crossState ,int curState) {
while (state < printCount) {
synchronized (this) {
while (state % crossState != curState) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ":" + state);
state++;
notifyAll();
}
}
}
public static void main(String[] args) {
CrossPrinter crossPrinter = new CrossPrinter(10);
// Thread A打印偶数
new Thread(() -> crossPrinter.printNumber(2,0), "Thread A").start();
// Thread B打印奇数
new Thread(() -> crossPrinter.printNumber(2,1), "Thread B").start();
}
}
新增 oneNum、twoNum 来记录前两个数
完整代码如下
public class CrossPrinter {
private int state;
private int oneNum;
private int twoNum;
private final int printCount;
public CrossPrinterThree(int printCount) {
this.state = 3;
this.oneNum = 1;
this.twoNum = 1;
this.printCount = printCount;
}
public static void main(String[] args) {
CrossPrinterThree crossPrinterThree = new CrossPrinter(10);
// 三线程交叉打印斐波那契数列
new Thread(() -> crossPrinterThree.printNum(3, 0), "Thread-A").start();
new Thread(() -> crossPrinterThree.printNum(3, 1), "Thread-B").start();
new Thread(() -> crossPrinterThree.printNum(3, 2), "Thread-C").start();
}
private void printNum(int crossState, int curState) {
while (state < printCount) {
synchronized (this) {
while (state % crossState != curState) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int curNum = oneNum + twoNum;
System._out_.println(Thread._currentThread_().getName() + ":" + curNum);
// 更新前两个数
oneNum = twoNum;
twoNum = curNum;
state++;
notifyAll();
}
}
}
}
实现方案:CountDownLatch
public class MultiThreadTaskExecution {
// 使用两个初始计数为1的CountDownLatch来实现一对多的通知机制
private CountDownLatch latchToB = new CountDownLatch(1);
private CountDownLatch latchToC = new CountDownLatch(1);
public void taskA() {
System.out.println("任务A执行中...");
try {
Thread.sleep(100); // 模拟任务A执行时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务A执行完毕,通知任务B、C开始执行...");
latchToB.countDown();
latchToC.countDown();
}
public void taskB() {
try {
latchToB.await();
System.out.println("任务B执行中...");
Thread.sleep(100); // 模拟任务B执行时间
System.out.println("任务B执行完毕...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void taskC() {
try {
latchToC.await();
System.out.println("任务C执行中...");
Thread.sleep(100); // 模拟任务C执行时间
System.out.println("任务C执行完毕...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MultiThreadTaskExecution taskExecution = new MultiThreadTaskExecution();
new Thread(taskExecution::taskB).start();
new Thread(taskExecution::taskC).start();
new Thread(taskExecution::taskA).start();
}
}
实现方案:CyclicBarrier
public class CyclicBarrierOne {
// 创建一个新的CyclicBarrier,当3个参与者到达时执行屏障操作
private CyclicBarrier barrier = new CyclicBarrier(3, () -> System._out_.println("所有线程到达屏障点,屏障操作执行!"));
public static void main(String[] args) {
CyclicBarrierOne cyclicBarrierOne = new CyclicBarrierOne();
new Thread(() -> cyclicBarrierOne.startTask(), "Thread-A").start();
new Thread(() -> cyclicBarrierOne.startTask(), "Thread-B").start();
new Thread(() -> cyclicBarrierOne.startTask(), "Thread-C").start();
}
private void startTask() {
System._out_.println(Thread._currentThread_().getName() + "开始执行任务...");
try {
Thread._sleep_(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System._out_.println(Thread._currentThread_().getName() + "到达屏障点,等待其他线程...");
try {
barrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System._out_.println(Thread._currentThread_().getName() + "继续执行后续操作");
}
}
public class SimultaneousStart {
private static final int _N _= 10;
_// 创建一个CountDownLatch用于线程启动的信号_
_ _private static final CountDownLatch _startSignal _= new CountDownLatch(1);
_// 创建一个 CountDownLatch 用于等待所有线程完成的信号_
_ _private static final CountDownLatch _doneSignal _= new CountDownLatch(_N_);
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
try {
_startSignal_.await(); _// 等待启动信号_
_ _System._out_.println(Thread._currentThread_().getName() + " has started");
Thread._sleep_(2000); _// 模拟任务执行_
_ _System._out_.println(Thread._currentThread_().getName() + " has finished");
} catch (InterruptedException e) {
Thread._currentThread_().interrupt();
} finally {
_doneSignal_.countDown(); _// 完成信号_
_ _}
};
_// 创建并启动N个线程_
_ _for (int i = 0; i < _N_; i++) {
new Thread(task, "Thread-" + (i + 1)).start();
}
_// 主线程等待片刻,确保所有线程已经启动并在等待_
_ _Thread._sleep_(1000);
System._out_.println("All threads are ready, starting now!");
_startSignal_.countDown(); _// 发出启动信号_
_ doneSignal_.await(); _// 等待所有线程完成_
_ _System._out_.println("All threads have finished executing.");
}
}
public class DeadlockExample {
// 创建两个资源
private static final Object _resourceOne _= new Object();
private static final Object _resourceTwo _= new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (resourceOne) {
System.out.println(Thread.currentThread().getName() + "locked resource1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceTwo) {
System.out.println(Thread.currentThread().getName() + "locked resource2");
}
}
}, "Thread-A").start();
new Thread(() -> {
synchronized (resourceTwo) {
System.out.println(Thread.currentThread().getName() + "locked resource2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resourceOne) {
System.out.println(Thread.currentThread().getName() + "locked resource1");
}
}
}, "Thread-B").start();
}
}
自定义条件变量
public class CustomLockExample {
private final Lock lock = new ReentrantLock();
private final Condition conditionA = lock.newCondition();
private final Condition conditionB = lock.newCondition();
private void methodA() throws InterruptedException {
lock.lock();
try {
System._out_.println("Thread A is waiting");
conditionA.await();
System._out_.println("Thread A is resumed");
} finally {
lock.unlock();
}
}
private void methodB() throws InterruptedException {
lock.lock();
try {
System._out_.println("Thread B is waiting");
conditionB.await();
System._out_.println("Thread B is resumed");
} finally {
lock.unlock();
}
}
private void resumeA() {
lock.lock();
try {
conditionA.signal(); _// Wake up one thread waiting on conditionA_
_ _System._out_.println("Signaled Thread A");
} finally {
lock.unlock();
}
}
private void resumeB() {
lock.lock();
try {
conditionB.signal(); _// Wake up one thread waiting on conditionB_
_ _System._out_.println("Signaled Thread B");
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
CustomLockExample example = new CustomLockExample();
Thread threadA = new Thread(() -> {
try {
example.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread threadB = new Thread(() -> {
try {
example.methodB();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
threadA.start();
threadB.start();
Thread._sleep_(2000); _// Pause to ensure threads reach wait state_
_ _example.resumeA(); _// Signal threadA_
_ _Thread._sleep_(2000);
example.resumeB(); _// Signal threadB_
_ _}
}
标志变量
public class FlagBasedControl {
private final Object lock = new Object();
private volatile boolean isThreadAWake = false;
private void methodA() throws InterruptedException {
synchronized (lock) {
while (!isThreadAWake) {
System._out_.println("Thread A is waiting");
lock.wait();
}
}
System._out_.println("Thread A is resumed and resetting flag");
isThreadAWake = false; _// Reset the flag for next use }_
_ _}
private void resumeA() {
synchronized (lock) {
isThreadAWake = true;
lock.notifyAll(); _// Wake up all threads, but only Thread A will proceed_
_ _System._out_.println("Signaled Thread A");
}
}
public static void main(String[] args) throws InterruptedException {
FlagBasedControl example = new FlagBasedControl();
Thread threadA = new Thread(() -> {
try {
example.methodA();
} catch (InterruptedException e) {
Thread._currentThread_().interrupt();
}
});
threadA.start();
Thread._sleep_(2000); _// Pause to ensure thread reaches wait state_
_ _example.resumeA(); _// Signal threadA_
_ _}
}