一:多线程打印问题
1.题目
有三个线程,线程名称分别为:a,b,c。每个线程打印自己的名称。
需要让他们同时启动,并按 c,b,a的顺序打印。
2.题解
2.1 思路分析
创建三个线程,分别命名为a,b,c。在b线程打印“b”之前,让它等待c线程结束;在a线程打印“a”之前,让它等待b线程结束。
2.2 代码实现
package Threading;
public class Test8 {
public static void main(String[] args) throws InterruptedException {
// 创建三个线程
Thread tc = new Thread(() -> {
// 打印c
System.out.print(Thread.currentThread().getName() + " ");
}, "c");
Thread tb = new Thread(() -> {
try {
// 等待c 执行完成
tc.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印b
System.out.print(Thread.currentThread().getName() + " ");
}, "b");
Thread ta = new Thread(() -> {
try {
// 等待b 执行完成
tb.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印a
System.out.print(Thread.currentThread().getName() + " ");
}, "a");
// 需要让他们同时启动,并按 c,b,a的顺序打印
ta.start();
tb.start();
tc.start();
}
}
二:多线程打印问题进阶版
1.题目
有三个线程,分别只能打印A,B和C。要求按顺序打印ABC,打印10次。
2.题解
2.1 思路分析
思路一:使用COUNT变量进行总控。
思路二:使用三个锁,分别控制。
2.2 代码实现
思路一代码实现:
package Threading;
public class Test9 {
private static volatile int COUNTER = 0;
private static Object lock = new Object();
public static void main(String[] args) {
// 创建三个线程,并指定线程名,每个线程名分别用A,B,C表示
Thread t1 = new Thread(() -> {
// 循环10次
for (int i = 0; i < 10; i++) {
// 执行的代码加锁
synchronized (lock) {
// 每次唤醒后都重新判断是否满足条件// 每条线程判断的条件不一样,注意线程t1,t2
while (COUNTER % 3 != 0) {
try {
// 不满足输出条件时,主动等待并释放锁
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 满足输出条件,打印线程名,每条线程打印的内容不同
System.out.print(Thread.currentThread().getName());
// 累加计数
COUNTER++;
// 唤醒其他线程
lock.notifyAll();
}
}
}, "A");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (COUNTER % 3 != 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName());
COUNTER++;
lock.notifyAll();
}
}
}, "B");
Thread t3 = new Thread(() -> {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
while (COUNTER % 3 != 2) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 换行打印
System.out.println(Thread.currentThread().getName());
COUNTER++;
lock.notifyAll();
}
}
}, "C");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}
思路二代码实现:
public class Test10 {
private static Object locker1 = new Object();
private static Object locker2 = new Object();
private static Object locker3 = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
synchronized (locker1) {
locker1.wait();
}
System.out.print("A");
synchronized (locker2) {
locker2.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
synchronized (locker2) {
locker2.wait();
}
System.out.print("B");
synchronized (locker3) {
locker3.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t3 = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
synchronized (locker3) {
locker3.wait();
}
System.out.println("C");
synchronized (locker1) {
locker1.notify();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
t3.start();
Thread.sleep(1000);
// 从线程 t1 启动
synchronized (locker1) {
locker1.notify();
}
}
}