目录
同步锁实现
juc锁实现
LockSupport 实现
队列实现
看着好多有面试题提到了这个,想到了java里可以用4种方式来实现。
同步锁实现
/** * 生产者-消费者 同步锁实现 */ public class ProducerAndConsumerSynchronized { public static void main(String[] args) throws InterruptedException { final Object object = new Object(); for (int i = 0;i < 5; i++) { Thread producer = new Thread("生产者"+(i+1)){ @Override public void run() { synchronized (object) { try { System.out.println(Thread.currentThread().getName()); object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread consumer = new Thread("消费者"+(i+1)){ @Override public void run() { synchronized (object) { System.out.println(Thread.currentThread().getName()); object.notifyAll(); } } }; producer.start(); consumer.start(); producer.join(); } } }juc锁实现
上面方式的使用juc中的工具类的实现方式
Lock 相当于 synchronized
Object 的 wait() 相当于 Condition 的 await()
Object 的 notifyAll() 相当于 Condition 的 signalAll()
/** * 生产者-消费者 juc实现 */ public class ProducerAndConsumerLock { public static void main(String[] args) throws InterruptedException { Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); for (int i = 0;i < 5; i++) { Thread producer = new Thread("生产者"+(i+1)){ @Override public void run() { lock.lock(); try { System.out.println(Thread.currentThread().getName()); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }; Thread consumer = new Thread("消费者"+(i+1)){ @Override public void run() { lock.lock(); try { System.out.println(Thread.currentThread().getName()); condition.signalAll(); } finally { lock.unlock(); } } }; producer.start(); consumer.start(); producer.join(); } } }LockSupport 实现
LockSupport 通过 sun.misc.Unsafe 实现线程阻塞和唤醒
/** * 生产者-消费者 juc LockSupport 实现 */ public class ProducerAndConsumerLockSupport { public static void main(String[] args) throws InterruptedException { for (int i = 0;i < 5; i++) { Thread producer = new Thread("生产者"+(i+1)){ @Override public void run() { System.out.println(Thread.currentThread().getName()); LockSupport.park(); } }; Thread consumer = new Thread("消费者"+(i+1)){ @Override public void run() { System.out.println(Thread.currentThread().getName()); LockSupport.unpark(producer); } }; producer.start(); consumer.start(); producer.join(); } } }队列实现
/** * 生产者-消费者 队列实现 */ public class ProducerAndConsumerQueue { static class Producer implements Runnable { public Producer(BlockingQueue<String> queue) { this.queue = queue; } BlockingQueue<String> queue; @Override public void run() { String name = Thread.currentThread().getName(); try { System.out.println("生产线程 " + name); queue.put(name); } catch (InterruptedException e) { e.printStackTrace(); } } } static class Consumer implements Runnable { public Consumer(BlockingQueue<String> queue) { this.queue = queue; } BlockingQueue<String> queue; @Override public void run() { try { String name = queue.take(); System.out.println("消费线程 " + name); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { BlockingQueue<String> queue = new LinkedBlockingQueue<>(1); Producer producer = new Producer(queue); Consumer consumer = new Consumer(queue); for (int i = 0; i < 5; i++) { new Thread(producer, "消息" + (i + 1)).start(); new Thread(consumer, "消费者" + (i + 1)).start(); } } }其中,同步锁、juc锁、LockSupport 也是线程通信。
两个线程交替打印
public class AlternatePrintExample { private static final Object lock = new Object(); private static int count = 1; private static final int MAX = 100; public static void main(String[] args) { Thread oddThread = new Thread(() -> { while (count <= MAX) { synchronized (lock) { if (count % 2 == 1) { System.out.println(Thread.currentThread().getName() + ": " + count); ++count; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }, "奇数"); Thread evenThread = new Thread(() -> { while (count <= MAX) { synchronized (lock) { if (count % 2 == 0) { System.out.println(Thread.currentThread().getName() + ": " + count); ++count; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } },"偶数"); oddThread.start(); evenThread.start(); } }