线程A、B、C分别打印1,2,3顺序执行10次
题目
线程A,B,C分别打印1,2,3; 并顺序执行10次;
解法一
基本思路
- 即根据题目意思, 要求使用三个线程分别命名为A, B, C; 并且线程A打印1, 线程B打印2, 线程C打印3, 按顺序执行10次;
- 可以利用
Semaphore
信号量实现, 利用acquire()
方法, 若不满足访问共享资源条件则会令当前线程阻塞; 和release()
方法, 释放资源, 并唤醒等待资源的线程;
实现代码
java
public class ThreeThreadsPrint123 {
public static void main(String[] args) {
// 信号量 控制访问资源的线程数量 设置线程数为0
Semaphore first = new Semaphore(0);
Semaphore second = new Semaphore(0);
Semaphore third = new Semaphore(0);
Thread t1 = new Thread(() -> {
for (int i = 0; i < 10; ++ i) {
try {
// 线程 A 打印 1
System.out.println("线程: " + Thread.currentThread().getName() + "打印: 1");
// 休眠一秒 便于观察结果
Thread.sleep(1000);
// release 会释放信号量 并唤醒等待线程
second.release();
// 尝试访问资源 因为允许0个线程访问 所以会阻塞线程 A
first.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "A");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; ++ i) {
try {
// 先阻塞线程B 保证线程A先打印结束后 再唤醒线程B
second.acquire();
// 线程 B 打印 2
System.out.println("线程: " + Thread.currentThread().getName() + "打印: 2");
// 休眠一秒 便于观察结果
Thread.sleep(1000);
// release 会释放信号量 并唤醒等待线程
third.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "B");
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10; ++ i) {
try {
// 先阻塞线程C 保证线程B先打印结束后 再唤醒线程C
third.acquire();
// 线程 C 打印 3
System.out.println("线程: " + Thread.currentThread().getName() + "打印: 3");
// 休眠一秒 便于观察结果
Thread.sleep(1000);
// release 会释放信号量 并唤醒等待线程
first.release();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "C");
t1.start();
t2.start();
t3.start();
}
}
解法二
基本思路
- 使用 synchronized 同步锁来实现, 使用
wait()
方法来让线程等待, 使用notifyAll()
方法来唤醒线程
实现代码
java
public class ThreeThreadsPrint123_2 {
// 计数器:计算当前打印次数
private int count = 0;
// 同步锁对象
private final Object lock = new Object();
// 打印方法:0打印A,1打印B,2打印C
public void printNum(int flag) {
for (int i = 0; i < 10; ++ i) {
synchronized (lock) {
while (count % 3 != flag && count < 30) {
try {
// 若没有轮到当前线程打印 则让当前线程等待
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if (count < 30) {
System.out.println("线程: " + Thread.currentThread().getName() + " 打印: " + (1 + flag));
// 次数增加
++ count;
// 唤醒所有线程
lock.notifyAll();
}
}
}
}
public static void main(String[] args) {
ThreeThreadsPrint123_2 obj = new ThreeThreadsPrint123_2();
Thread t1 = new Thread(() -> obj.printNum(0), "A");
Thread t2 = new Thread(() -> obj.printNum(1), "B");
Thread t3 = new Thread(() -> obj.printNum(2), "B");
t2.start();
t1.start();
t3.start();
}
}