加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

在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)循环内).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读