多线程交替打印的几种解法
常见解法:
1. synchronized+wait/notify
2. join()
3. 自旋+volatile
4. Lock
5. Lock+Condition
6. Semaphore
1. synchronized 关键字
//一个线程打印1~ 52,另一个线程打印A~Z,打印顺序是12A34B…5152Z
public class TakeTurnsPrint {
private boolean flag;
private int count;
public synchronized void printNum() {
for (int i = 0; i < 26; i++) {
//虚假唤醒”(spurious wakeup)的问题,线程可能在既没有被notify/notifyAll,也没有被中断或者超时的情况下被唤醒,这种唤醒是我们不希望看到的
//这样即便被虚假唤醒了,也会再次检查while里面的条件,如果不满足条件,就会继续wait
while (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.print(++count);
System.out.print(++count);
notify();
}
}
public synchronized void printLetter() {
for (int i = 0; i < 26; i++) {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
flag = !flag;
System.out.print((char) (65 + i));
notify();
}
}
public static void main(String[] args) {
TakeTurnsPrint turnsPrint = new TakeTurnsPrint();
new Thread(() -> turnsPrint.printNum()).start();
new Thread(() -> turnsPrint.printLetter()).start();
}
}
2. Lock 显式锁
3. semaphore 信号量
信号量是信号量,和线程没有关系
信号量与特定的资源一一对应,即1个信号量一定是控制一个资源的。
信号量, 可以用来控制当下可访问特定资源的线程数量;
a.acquire() 线程获取一个a信号量的令牌 a-1
b.release() b信号量增加一个令牌,唤醒一个获取令牌不成功的阻塞线程b+1
// 三个线程循环依次打印ABC
public class TakeTurnsPrint_Semaphore {
Semaphore a= new Semaphore(1);
Semaphore b= new Semaphore(0);
Semaphore c= new Semaphore(0);
void printA() {
try {
for (int i = 0; i < 10; i++) {
a.acquire();
System.out.println(Thread.currentThread().getName());
b.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void printC() {
try {
for (int i = 0; i < 10; i++) {
c.acquire();
System.out.println(Thread.currentThread().getName());
a.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void printB() {
try {
for (int i = 0; i < 10; i++) {
b.acquire();
System.out.println(Thread.currentThread().getName());
c.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TakeTurnsPrint_Semaphore t=new TakeTurnsPrint_Semaphore();
new Thread(()->t.printA(),"A").start();
new Thread(()->t.printB(),"B").start();
new Thread(()->t.printC(),"C").start();
}
}

浙公网安备 33010602011771号