题目:
有两个线程t1和t2,t1打印123,t2打印ABC,现在需要实现两个线程交替打印为"1A2B3C"
关于这道题我们可以提供多种思路来实现交替打印的结果,例如wait-notify、lock-condition ,以及Semaphore 以及yeild
先使用wait-notify
java
public class PrintingWithWaitNotify {
private static final Object lock = new Object();
private static boolean printNumber = true;
public static void main(String[] args) {
Thread numberThread = new Thread(new NumberPrinter());
Thread letterThread = new Thread(new LetterPrinter());
numberThread.start();
letterThread.start();
}
static class NumberPrinter implements Runnable {
@Override
public void run() {
synchronized (lock) {
try {
for (int i = 1; i <= 3; i++) {
while (!printNumber) {
lock.wait();
}
System.out.print(i);
printNumber = false;
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class LetterPrinter implements Runnable {
@Override
public void run() {
synchronized (lock) {
try {
for (char c = 'A'; c <= 'C'; c++) {
while (printNumber) {
lock.wait();
}
System.out.print(c);
printNumber = true;
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
使用lock-condition
java
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintingWithReentrant {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Thread thread1 = new Thread(new PrintNumbers(lock, condition));
Thread thread2 = new Thread(new PrintLetters(lock, condition));
thread1.start();
thread2.start();
}
}
class PrintNumbers implements Runnable {
private Lock lock;
private Condition condition;
public PrintNumbers(Lock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
lock.lock();
try {
System.out.print(i);
condition.signal(); // 唤醒打印字母的线程
if (i < 3) {
condition.await(); // 等待打印字母的线程执行
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}
}
class PrintLetters implements Runnable {
private Lock lock;
private Condition condition;
public PrintLetters(Lock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
for (char letter = 'A'; letter <= 'C'; letter++) {
lock.lock();
try {
System.out.print(letter);
condition.signal(); // 唤醒打印数字的线程
if (letter < 'C') {
condition.await(); // 等待打印数字的线程执行
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}
}
使用 Semaphore
java
import java.util.concurrent.Semaphore;
public class PrintingWithSemaphore {
private static final Semaphore semaphoreNumber = new Semaphore(1);
private static final Semaphore semaphoreLetter = new Semaphore(0);
public static void main(String[] args) {
Thread numberThread = new Thread(new NumberPrinter());
Thread letterThread = new Thread(new LetterPrinter());
numberThread.start();
letterThread.start();
}
static class NumberPrinter implements Runnable {
@Override
public void run() {
try {
for (int i = 1; i <= 3; i++) {
semaphoreNumber.acquire();
System.out.print(i);
semaphoreLetter.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class LetterPrinter implements Runnable {
@Override
public void run() {
try {
for (char c = 'A'; c <= 'C'; c++) {
semaphoreLetter.acquire();
System.out.print(c);
semaphoreNumber.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
使用yeild
java
public class PrintingWithYeild {
private static volatile boolean printNumber = true;
public static void main(String[] args) {
Thread numberThread = new Thread(new NumberPrinter());
Thread letterThread = new Thread(new LetterPrinter());
numberThread.start();
letterThread.start();
}
static class NumberPrinter implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
while (!printNumber) {
Thread.yield();
}
System.out.print(i);
printNumber = false;
Thread.yield();
}
}
}
static class LetterPrinter implements Runnable {
@Override
public void run() {
for (char c = 'A'; c <= 'C'; c++) {
while (printNumber) {
Thread.yield();
}
System.out.print(c);
printNumber = true;
Thread.yield();
}
}
}
}