這兩天在知乎上看到不一樣的人都問了這個問題,回想起當年找實習的時候也寫過這個問題,以爲還蠻有意思的,就在這裏記錄一下。
最多見的是使用 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 等等。線程