在Java中使用wait()和notify()进行阻止
发布时间:2020-12-15 04:35:15 所属栏目:Java 来源:网络整理
导读:我正在使用 Java中的wait()和notify()编写生产者和消费者代码. 创建Thread-0并在produce()上调用,并创建Thread-1并在consume()上调用. public class Processor { private volatile ListInteger list = new ArrayList(); private final int MAX_CAPACITY = 5;
我正在使用
Java中的wait()和notify()编写生产者和消费者代码.
创建Thread-0并在produce()上调用,并创建Thread-1并在consume()上调用. public class Processor { private volatile List<Integer> list = new ArrayList<>(); private final int MAX_CAPACITY = 5; Object lock = new Object(); public void produce() throws InterruptedException { while (true) { while (list.size() == MAX_CAPACITY) { System.out.println("List is full! Producer is Waiting...."); synchronized (lock) { lock.wait(); } } synchronized (lock) { int random = new Random().nextInt(100); list.add(random); System.out.println("Added to list:" + random); lock.notify(); } } } public void consume() throws InterruptedException { while (true) { while (list.size() == 0) { System.out.println("List is empty!! Consumer is Waiting..."); synchronized (lock) { lock.wait(); } } synchronized (lock) { int i = list.remove(0); System.out.println("Removed from list:" + i); lock.notify(); } } } } 问题是在执行期间,程序在produce()之后停止: List is empty!! Consumer is Waiting... Added to list:22 Added to list:45 Added to list:72 Added to list:91 Added to list:51 List is full! Producer is Waiting.... 我无法理解这里的问题是什么.我以某种方式弄清楚将while循环中的代码包装在produce()和consume()中的synchronized块中解决了这个问题. 生产() synchronized (lock) { while (list.size() == MAX_CAPACITY) { System.out.println("List is full! Producer is Waiting...."); lock.wait(); } 消耗 synchronized (lock) { while (list.size() == 0) { System.out.println("List is empty!! Consumer is Waiting..."); lock.wait(); } } 这是什么问题?这是线程饥饿还是死锁的情况? 编辑:调用类: public class App { public static void main(String[] args) { final Processor processor = new Processor(); Runnable r1 = new Runnable() { @Override public void run() { try { processor.produce(); } catch (InterruptedException e) { e.printStackTrace(); } } }; Runnable r2 = new Runnable() { @Override public void run() { try { processor.consume(); } catch (InterruptedException e) { e.printStackTrace(); } } }; Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } } 解决方法
当你执行list.size()时,它不是线程安全的,并且没有保证你将看到另一个线程中的值发生了变化.如果JIT检测到您没有在该线程中更改它,则它甚至可以内联该值.
通过将同步块放在循环外部,可确保值的变化可见(因为它也在while(true)循环内). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |