代码如下
public synchronized void put(Object o) { while (buf.size()==MAX_SIZE) { wait(); // 如果buffer为full,就会执行wait方法等待(为了简单,我们省略try/catch语句块) } buf.add(o); notify(); // 通知所有正在等待对象锁的Producer和Consumer(译者注:包括被阻挡在方法外的Producer和Consumer) } // Y: 这里是C2试图获取锁的地方(原作者将这个方法放到了get方法里面,此处,我把它放在了方法的外面) public synchronized Object get() { while (buf.size()==0) { wait(); // 如果buffer为Null,就会执行wait方法(为了简单,同样省略try/catch语句块) // X: 这里是C1试图重新获得锁的地方(看下面代码) } Object o = buf.remove(0); notify(); // 通知所有正在等待对象锁的Producer和Consumer(译者注:包括被阻挡在方法外的Producer和Consumer) return o; }
这里如果不用while用if会出现什么情况呢:(生产者P,消费者C)
1.buf.size() == 0时,C1进入,if判断为真,wait(抛出锁);C2在外等待
2.P1获得锁,add后buf == 1,唤醒C1
3.被唤醒的C1和C2抢锁,C2获得锁执行remove,此时buf.size()==0
4.C1此时获得锁,继续往下执行buf.remove但是此时buf.size()==0,抛出IndexArrayOutOfBoundsException
这里使用while判断就能避免此问题
这里使用notify会有什么问题呢,情景如下:(max_size == 1)
1.P1执行
2.P2,P3想put但是buf.size()==1 两个都wait
3.C1,C2同时想get,C1获得锁,get完buf.size()==0 并唤醒P2
4.C2,P2抢锁C2抢得,wait
5.P2获得锁Put后,buf.size()==1 唤醒P3
6.P3获得锁 wait 此时C2和P3同时wait,没有线程能notify了
如果使用notifyall可避免这种情况
相关推荐
本示例中的“生产者-消费者”模型是一种经典的多线程问题,它模拟了实际生产环境中的资源分配与消耗过程。下面我们将详细探讨如何在Java中实现这个模型。 首先,我们要理解生产者-消费者模型的基本概念。在这个模型...
在Java中,我们可以利用同步机制来实现这种关系,确保生产者和消费者之间正确、有序地交互。 首先,理解生产者消费者模型的核心概念。生产者将产品放入一个共享的缓冲区,而消费者从缓冲区取出产品进行消费。关键...
在Java多线程编程中,消费者-生产者模型是一种经典的线程间通信模式,用于解决多线程环境...总之,消费者-生产者模型是Java多线程编程中的一个重要概念,掌握其原理和实现对于构建高效、可靠的多线程应用程序至关重要。
在这个例子中,我们创建了一个`Buffer`类作为共享资源,`Producer`和`Consumer`类分别代表生产者和消费者。`Buffer`类中的`put()`和`take()`方法使用`synchronized`关键字保证了线程安全,并使用`wait()`和`...
生产者消费者模型是多线程编程中的一个经典设计模式,主要用来解决生产者(生产数据的线程)和消费者(消费数据的线程)之间的同步和通信问题。在这个模型中,生产者生产产品并将其放入一个共享的容器,而消费者则从...
在Java编程中,线程间的通信是多线程编程中的一个重要概念,特别是在处理并发和协作任务时。生产者消费者模型是一种经典的线程同步问题,它模拟了实际生活中的生产过程和消费过程,使得生产者线程可以将数据生产出来...
在这个例子中,我们使用一个LinkedList作为共享的缓冲区,生产者和消费者共享对这个队列的访问,并通过wait/notify进行同步。当队列满时,生产者会被阻塞;当队列空时,消费者会被阻塞。当队列状态改变时,使用...
Java线程实现的生产者和消费者程序是一种经典的多线程设计模式,用于处理并发操作中的数据共享问题。这种模式在实际编程中广泛应用,特别是在需要高效处理数据流和资源管理的系统中。以下将详细讲解其核心概念、实现...
在计算机操作系统中,生产者-消费者模型是一种常见的同步机制,用于解决多线程之间的数据共享和访问问题。在 Java 中,我们可以使用多线程编程和同步机制来实现生产者-消费者模型。 生产者-消费者模型的定义 生产...
【Java多线程中的生产者与消费者问题】 在Java编程中,多线程是一个关键特性,它允许多个任务在同一个程序中并发执行。在实际应用中,常常会出现一类问题,即生产者与消费者问题,这是一个典型的并发控制问题。在这...
在这个例子中,`put()` 方法是生产者,`get()` 方法是消费者。当缓冲区中有数据时,消费者调用`get()`并消费数据,然后调用`wait()`让自己进入等待状态;生产者则在缓冲区空时调用`put()`,填入数据并唤醒消费者。...
在这个例子中,我们使用了一个`LinkedList`作为缓冲区,并通过`synchronized`和`wait/notify`机制实现了生产者和消费者之间的同步。 解决生产者与消费者问题有助于理解和掌握多线程编程中的同步与通信,这对于构建...
生产者与消费者问题是多线程编程中的一个经典问题,它主要涉及到线程间的协作与同步。在Java中,我们可以利用其内置的并发工具类来解决这个问题。本篇将深入探讨如何使用Java实现生产者和消费者的模型,并通过具体的...
Java线程中的并发协作模型是多线程编程中一个核心的概念,它主要通过生产者消费者模型来体现。在这个模型中,生产者线程负责创建或生产资源,而消费者线程则负责消耗这些资源。为了保证线程之间的协作和数据的一致性...
生产者消费者问题是多线程编程中的经典模型,用于展示如何在并发环境中协调生产者和消费者之间的数据处理。在这个问题中,生产者线程负责生成数据,而消费者线程则负责消费这些数据。Java语言提供了丰富的工具来解决...
在Java编程领域,生产者消费者问题是多线程同步的一个经典示例,它源自并发编程中的一个常见场景。这个问题描述了两个角色:生产者和消费者,它们共享一个有限大小的缓冲区。生产者负责生成数据并将数据放入缓冲区,...
在这个例子中,生产者和消费者都是独立的线程,它们通过`BlockingQueue`进行交互。`ArrayBlockingQueue`保证了线程安全,因此无需手动处理同步问题。 4. **适用场景**:生产者-消费者模式广泛应用于多线程系统,如...
在Android开发中,生产者-消费者模式是一种常见的多线程设计模式,用于处理并发问题,尤其是在数据处理和异步操作中。这个模式的核心思想是通过一个共享的数据缓冲区,使得生产者线程可以生成数据并放入缓冲区,而...
在Java编程中,"生产者与消费者"模式是一种经典的多线程问题,它涉及到了并发处理和资源管理。这个模式的核心思想是通过共享一个有限的缓冲区,使得生产者线程可以将产品放入缓冲区,而消费者线程则可以从缓冲区取出...
生产者消费者问题是多线程编程中的经典问题,主要涉及到线程间的协作与同步。在Java中,这个问题通常通过使用线程安全的数据结构(如`BlockingQueue`)和同步原语(如`synchronized`关键字、`wait()`、`notify()`或`...