✅两个线程,一个打印奇数,一个打印偶数,然后顺序打印出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();
                }
            }
        }
    }
}

原文: https://www.yuque.com/hollis666/xkm7k3/du59bprsiplax72p