这两天在知乎上看到不一样的人都问了这个问题,回想起当年找实习的时候也写过这个问题,以为还蛮有意思的,就在这里记录一下。
最多见的是使用 notify() wait()java
public class Demo { public static void main(String[] args) { Object lock = new Object(); new Printer("线程 A", lock).start(); new Printer("线程 B", lock).start(); } private static class Printer extends Thread { private final Object lock; public Printer(String name, Object lock) { super(name); this.lock = lock; } @Override public void run() { for (char i = 'A'; i <= 'Z'; i++) { synchronized (lock) { System.out.println(getName() + " 打印字母: " + i); lock.notify(); try { Thread.sleep(500); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }
不使用锁ide
public class Demo { /** * 使用计数器,两个线程分别在计数器为奇数/偶数时打印, * 使用AtomicBoolean更简单,这里使用AtomicInteger * 是考虑可拓展为N个线程交替打印 */ public static void main(String[] args) { AtomicInteger counter = new AtomicInteger(0); new PrinterA("线程 A", counter).start(); new PrinterB("线程 B", counter).start(); } private static class PrinterA extends Thread { private final AtomicInteger counter; public PrinterA(String name, AtomicInteger counter) { super(name); this.counter = counter; } @Override public void run() { for (char i = 'A'; i <= 'Z'; ) { if (counter.get() % 2 == 0) { System.out.println(getName() + " 打印字母: " + i++); counter.incrementAndGet(); } } } } private static class PrinterB extends Thread { private final AtomicInteger counter; public PrinterB(String name, AtomicInteger counter) { super(name); this.counter = counter; } @Override public void run() { for (char i = 'A'; i <= 'Z'; ) { if (counter.get() % 2 != 0) { System.out.println(getName() + " 打印字母: " + i++); counter.incrementAndGet(); } } } } }
使用 ReentrantLockthis
public class Demo { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Condition aPrintCondition = lock.newCondition(); Condition bPrintCondition = lock.newCondition(); Condition cPrintCondition = lock.newCondition(); new Printer("线程 A", lock, aPrintCondition, bPrintCondition).start(); new Printer("线程 B", lock, bPrintCondition, cPrintCondition).start(); new Printer("线程 C", lock, cPrintCondition, aPrintCondition).start(); } private static class Printer extends Thread { private final ReentrantLock lock; private final Condition waitCondition; private final Condition signalCondition; public Printer(String name, ReentrantLock lock, Condition waitCondition, Condition signalCondition) { super(name); this.lock = lock; this.waitCondition = waitCondition; this.signalCondition = signalCondition; } @Override public void run() { for (char i = 'A'; i <= 'Z'; i++) { lock.lock(); try { System.out.println(getName() + " 打印字母: " + i); Thread.sleep(500); signalCondition.signal(); waitCondition.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } } }
还能够使用其余juc包里的同步类 Semaphore 等等。线程