在之前的Java多线程--生产者和消费者问题的初尝试中,使用的是Synchronized关键字来同步。本次将使用ReentrantLock锁对象来完成线程间的同步。
生产者代码:
package JavaDay5_19.JavaMultithreading; import java.util.Queue; import java.util.concurrent.locks.ReentrantLock; /** * @author [email protected] * @date 18-5-19 上午10:33 */ public class Producer implements Runnable { private Queue<Integer> products; private ReentrantLock lock; public Producer(Queue<Integer> products, ReentrantLock lock) { this.products = products; this.lock = lock; } @Override public void run() { for(int i = 0; i <= 4; i++) { try { lock.lock(); if(products.size() == 2) { System.out.println("存货已满"); i--; } else { products.offer(i); System.out.println("Producing " + i); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
消费者代码:
package JavaDay5_19.JavaMultithreading; import java.util.Queue; import java.util.concurrent.locks.ReentrantLock; /** * @author [email protected] * @date 18-5-19 上午10:22 */ public class Consumer implements Runnable { private Queue<Integer> products; private ReentrantLock lock; public Consumer(Queue<Integer> products, ReentrantLock lock) { this.products = products; this.lock = lock; } @Override public void run() { while(true) { try { lock.lock(); if (products.isEmpty()) { System.out.println("商品缺货..."); } else { int number = products.poll(); System.out.println("Consuming " + number); if (number == 4) { break; } } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
测试代码:
package JavaDay5_19.JavaMultithreading; import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.locks.ReentrantLock; /** * @author [email protected] * @date 18-5-19 上午10:38 */ public class Test { public static void main(String[] args) { Queue<Integer> product = new LinkedList<>(); ReentrantLock lock = new ReentrantLock(); Thread producer = new Thread(new Producer(product, lock)); Thread consumer = new Thread(new Consumer(product, lock)); producer.start(); consumer.start(); } }
运行结果:
将Producer类中sleep时间改为3后,代码如下:
package JavaDay5_19.JavaMultithreading; import java.util.Queue; import java.util.concurrent.locks.ReentrantLock; /** * @author [email protected] * @date 18-5-19 上午10:33 */ public class Producer implements Runnable { private Queue<Integer> products; private ReentrantLock lock; public Producer(Queue<Integer> products, ReentrantLock lock) { this.products = products; this.lock = lock; } @Override public void run() { for(int i = 0; i <= 4; i++) { try { lock.lock(); if(products.size() == 2) { System.out.println("存货已满"); i--; } else { products.offer(i); System.out.println("Producing " + i); } } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); try { Thread.sleep(3);//此处改为3 } catch (InterruptedException e) { e.printStackTrace(); } } } } }
测试结果如下:
总结:感觉两种同步方式各有各的优点,暂时还不太能分清,之后会再次介绍。