多线程练习(三)三个线程交互打印

曾经有面试官问过这样一个问题,如何让两个线程交替打印奇数和偶数?如何让多个线程交替执行?
回答这个问题之前需要先了解java多线程的运行机制,线程间通信机制,线程同步问题。
这个问题我知道的实现方案有两种,一种是基于synchronized和wait/notify,另外一种是基于Lock和Condition.
1.基于synchronized和wait/notify

public class ChangeABC { private Object lock = new Object(); private boolean RUN0 = true; private static final int LIMIT = 10; public static void main(String[] args) throws InterruptedException { final ChangeABC o = new ChangeABC(); new Thread(new Runnable() { @Override public void run() { try { o.m0(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t0").start(); new Thread(new Runnable() { @Override public void run() { try { o.m1(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "t1").start(); Thread.sleep(10 * 1000); }private void m1() throws InterruptedException { for (int i = 1; i < LIMIT; i += 2) { synchronized (lock) { if (RUN0) { lock.wait(); } System.out.println(Thread.currentThread().getName() + "___" + i); RUN0 = true; lock.notify(); } } }private void m0() throws InterruptedException { for (int i = 0; i < LIMIT; i += 2) { synchronized (lock) { if (!RUN0) { lock.wait(); } System.out.println(Thread.currentThread().getName() + "___" + i); RUN0 = false; lock.notify(); } } } }

2.基于Lock和Condition
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /*** 线程间通信-基于lock的condition* @date 2017年12月21日*/ public class ChangeABC1 { private Lock lock = new ReentrantLock(); private Condition c0 = lock.newCondition(); private Condition c1 = lock.newCondition(); private Condition c2 = lock.newCondition(); private int status = 0; private static final int LIMIT = 10; public static void main(String[] args) throws InterruptedException { ExecutorService exec = new ThreadPoolExecutor(3, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(300), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); final ChangeABC1 o = new ChangeABC1(); exec.submit(o.createTask(0)); exec.submit(o.createTask(1)); exec.submit(o.createTask(2)); exec.shutdown(); exec.awaitTermination(5, TimeUnit.MINUTES); }/*** @param name* @param i*/ private Runnable createTask(final int i) { return new Runnable() { @Override public void run() { try { m(i); } catch (InterruptedException e) { e.printStackTrace(); } } }; }private void m(final int n) throws InterruptedException { for (int i = n; i < LIMIT; i += 3) { lock.lock(); try { switch (n) { case 0: if (status != 0) { c0.await(); } System.out.println(Thread.currentThread().getName() + "___" + i); status = 1; c1.signal(); break; case 1: if (status != 1) { c1.await(); } System.out.println(Thread.currentThread().getName() + "___" + i); status = 2; c2.signal(); break; case 2: if (status != 2) { c2.await(); } System.out.println(Thread.currentThread().getName() + "___" + i); status = 0; c0.signal(); break; default: break; } } finally { lock.unlock(); } } } }

【多线程练习(三)三个线程交互打印】链接:https://www.jianshu.com/p/dcc66a6f37cb

    推荐阅读