✅两个线程,一个打印奇数,一个打印偶数,然后顺序打印出1-100
这是一个比较经典的多线程之间协调与通信的问题,首先比较容易想到的就是使用wait notify,两个线程之间互相等待,并互相通信。
/**
* 使用wait notify
* @author Hollis
*/
public class SequentialPrinter {
private static final Object lock = new Object();
private static int number = 1;
private static final int MAX_NUMBER = 100;
public static void main(String[] args) {
Thread oddThread = new Thread(new OddPrinter());
Thread evenThread = new Thread(new EvenPrinter());
oddThread.start();
evenThread.start();
}
static class OddPrinter implements Runnable {
@Override
public void run() {
while (number <= MAX_NUMBER) {
synchronized (lock) {
if (number % 2 == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(number);
number++;
lock.notify();
}
}
}
}
}
static class EvenPrinter implements Runnable {
@Override
public void run() {
while (number <= MAX_NUMBER) {
synchronized (lock) {
if (number % 2 == 1) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(number);
number++;
lock.notify();
}
}
}
}
}
}在这个示例中,我们使用了 wait() 和 notify() 方法来实现线程之间的通信和协调。
OddPrinter 用来打印奇数,EvenPrinter 用来打印偶数,当一个线程在打印完数字后,会使用 notify() 唤醒另一个线程。这样,两个线程会交替执行,从而保证了顺序输出的要求。
除了wait-notify机制,还可以使用ReentrantLock和Condition。下面是一个使用这些类的示例代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用ReentrantLock+Condition
* @author Hollis
*/
public class SequentialPrinterWithLock {
private static final Lock lock = new ReentrantLock();
private static final Condition oddCondition = lock.newCondition();
private static final Condition evenCondition = lock.newCondition();
private static int number = 1;
private static final int MAX_NUMBER = 100;
public static void main(String[] args) {
Thread oddThread = new Thread(new OddPrinter());
Thread evenThread = new Thread(new EvenPrinter());
oddThread.start();
evenThread.start();
}
static class OddPrinter implements Runnable {
@Override
public void run() {
while (number < MAX_NUMBER) {
lock.lock();
try {
if (number % 2 == 0) {
oddCondition.await();
}
System.out.println(number);
number++;
evenCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
static class EvenPrinter implements Runnable {
@Override
public void run() {
while (number < MAX_NUMBER) {
lock.lock();
try {
if (number % 2 != 0) {
evenCondition.await();
}
System.out.println(number);
number++;
oddCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}还可以使用Java提供的 Semaphore 等并发工具来实现线程的协调和顺序打印。下面是一个使用 Semaphore 的示例代码:
import java.util.concurrent.Semaphore;
/**
* 使用信号量
* @author hollis
*/
public class SequentialPrinterWithSemaphore {
private static final Semaphore oddSemaphore = new Semaphore(1);
private static final Semaphore evenSemaphore = new Semaphore(0);
private static int number = 1;
private static final int MAX_NUMBER = 100;
public static void main(String[] args) {
Thread oddThread = new Thread(new OddPrinter());
Thread evenThread = new Thread(new EvenPrinter());
oddThread.start();
evenThread.start();
}
static class OddPrinter implements Runnable {
@Override
public void run() {
while (number < MAX_NUMBER) {
try {
oddSemaphore.acquire();
if (number % 2 == 0) {
oddSemaphore.release();
} else {
System.out.println(number);
number++;
evenSemaphore.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class EvenPrinter implements Runnable {
@Override
public void run() {
while (number < MAX_NUMBER) {
try {
evenSemaphore.acquire();
if (number % 2 == 1) {
evenSemaphore.release();
} else {
System.out.println(number);
number++;
oddSemaphore.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}