`

Java并发:wait()、notify()、notifyAll()实现生产者-消费者模式

阅读更多

Java中根类 Object中 wait()、notify()、notifyAll() 三个方法都是native修饰的方法。 每个对象都有相对应的方法,使用这三种方法的前提是,正在运行的线程必须拥有该对象的锁,即在synchronized(){}中。

 

wait():当前线程放弃该对象的锁,线程处于休眠状态,直到notify()或者notifyAll()之后,才有可能继续执行。

notify():唤醒某个放弃该对象锁的线程。

notifyAll():唤醒全部放弃该对象锁的线程。

 

 

 

注意:wait() 和sleep() 两者的共同点都是使当前线程放弃CPU控制权,线程处于挂起状态,但是wait()方法会放弃synchronized块中对象的锁,但是sleep()方法却不会释放掉synchronized块中对象的锁。sleep()方法是Thread对象中的方法, wait()方法是每个对象都有的。

 

 

下面是一个比较经典的生产者-消费者模式的多线程例子:

 

 

 

package thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author:zyy
 * @名称: 生产者-消费者
 * 
 */
public class ProduceAndConsumer {
	public static void main(String[] args) {
		Product pro = new Product();
		Thread thread1 = new Thread(new Produce(pro),"thread1");
		Thread thread2 = new Thread(new Consumer(pro),"thread2");
		Thread thread3 = new Thread(new Produce(pro),"thread3");
		Thread thread4 = new Thread(new Consumer(pro),"thread4");
		ExecutorService servicePool = Executors.newCachedThreadPool();
		
		servicePool.execute(thread1);
		servicePool.execute(thread2);
		servicePool.execute(thread3);
		servicePool.execute(thread4);
//		
//		thread1.start();
//		thread2.start();
//		thread3.start();
//		thread4.start();		
//		
		
	}
}


class Product {
	
	private int size ;  //当前容量
	
	private int MAX_SIZE = 10;  //最大容量
	
	/**
	 * 消费
	 */
	public synchronized void get(){
		while(size<=0){
			System.out.println("没有商品,为空");
			try {
				this.wait();  //当没有东西可以消费的话,当前线程放弃Product对象的锁,直到有别的线程唤醒该对象锁
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "  --");
		}
		
		System.out.println("开始消费  --" + size--);
		//消费了之后,就唤醒之前放弃该对象锁的线程,(注意: 虽然notify()唤醒了,但是必须要等到该synchronized内的代码块执行完毕)
		this.notify();  
	}
	
	/**
	 * 生产
	 */
	public synchronized void add(){
		while(size>=MAX_SIZE){
			System.out.println("商品已经满了,不能存放");
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("开始生产 --" + size++);  
		this.notify(); //生产了,然后之前放弃该对象锁的线程
	}
	
}

class Produce implements Runnable{

	private Product product;

	public Produce(Product product) {
		super();
		this.product = product;
	}

	@Override
	public void run() {
		while(true){
			product.add();
		/*	try {
				TimeUnit.SECONDS.sleep(1);  //这里设置时间,可以更直观的观看消费的情况
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}*/
		}
	}
	
}


class Consumer implements Runnable{

	private Product product;

	public Consumer(Product product) {
		super();
		this.product = product;
	}
	
	@Override
	public void run() {
		while(true){
			product.get();	
//			try {
//				TimeUnit.SECONDS.sleep(2);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
		}
	}
	
}

 

 

如有不正确,欢迎拍砖!

0
4
分享到:
评论

相关推荐

    java多线程实现生产者和消费者

    通过理解和掌握这些知识点,开发者能够有效地实现生产者-消费者模式,解决并发编程中的数据共享和协作问题。在实际项目中,这个模式常用于优化系统性能,尤其是在I/O密集型或计算密集型的应用中。

    JAVA_生产者-消费者

    在Java编程中,"生产者-消费者"模式是一种经典的多线程问题,它涉及到了并发处理和资源管理。这个模式的主要目标是通过分离生产数据和消费数据的过程,提高系统的效率和灵活性。在这个模式中,"生产者"负责生成数据...

    Java多线程实现生产者消费者

    这就是一个基本的Java“生产者-消费者”模型实现。通过这样的设计,我们可以有效地控制生产者和消费者的执行顺序,确保了数据的正确性,并且避免了先消费后生产的情况。在实际应用中,可能需要根据具体需求进行优化...

    用多线程同步方法解决生产者-消费者问题

    3. **线程同步原语**:在实现中,可以利用Java的`synchronized`关键字、`wait()`、`notify()`或`notifyAll()`方法,或者C++中的`std::mutex`、`std::condition_variable`等同步原语。 4. **数据结构设计**:为了...

    procon.rar_ProCon.d_生产 者- 消费者 问题_生产者

    生产者-消费者问题是一个经典的多线程同步问题,它源于计算机科学中的并发编程领域。这个问题由计算机科学家Edsger W. Dijkstra提出,主要探讨如何在多线程环境下有效地管理和控制资源的生产和消费,以避免数据竞争...

    多线程_生产者与消费者模式示例

    线程池可以配合生产者消费者模式,例如通过提交任务到线程池来实现生产者,线程池中的工作线程充当消费者角色。 在使用生产者消费者模式时,需要注意以下几点: - **线程安全**:确保所有的操作都是线程安全的,...

    基于JAVA线程机制研究生产者-消费者问题.pdf

    在Java中实现生产者-消费者问题不仅能够加深对Java多线程编程的理解,还能够锻炼出良好的并发编程思维,这对于未来在软件工程和系统开发等领域的工作至关重要。 总之,基于Java线程机制研究生产者-消费者问题,通过...

    【IT十八掌徐培成】Java基础第08天-05.多线程-生产者-消费者2.zip

    在Java中实现生产者-消费者模型,主要依赖于线程同步机制,包括`wait()`, `notify()` 和 `notifyAll()` 方法,它们都是在 `Object` 类中定义的。这些方法配合 `synchronized` 关键字使用,可以确保线程安全地访问...

    模拟生产者消费者问题(java)

    在计算机科学中,生产者-消费者问题是多线程并发控制中的一个经典问题。它描述了两个不同的线程,生产者负责生成数据,而消费者则负责消耗这些数据。在这个Java实现中,我们将探讨如何使用Java的并发工具来解决这个...

    android 生产者消费者模式

    在Android开发中,生产者-消费者模式是一种常见的多线程设计模式,用于处理并发问题,尤其是在数据处理和异步操作中。这个模式的核心思想是通过一个共享的数据缓冲区,使得生产者线程可以生成数据并放入缓冲区,而...

    生产者与消费者java实现源代码

    以下是对生产者-消费者问题及其Java实现的详细解析: 1. **生产者-消费者模型**: - **生产者**:负责生产数据并将其放入一个共享的数据缓冲区。 - **消费者**:从共享缓冲区中取出数据并进行处理。 - **缓冲区*...

    java代码-wait-notify 生产者消费者

    7. **Java并发工具类**:除了`wait()`和`notify()`,Java并发库提供了更高级的工具,如`BlockingQueue`,它提供了线程安全的队列操作,简化了生产者消费者模式的实现,避免了直接使用`wait()`和`notify()`可能导致的...

    操作系统生产者与消费者问题Java简单模拟实现

    操作系统中的生产者-消费者问题是多线程编程中的经典案例,主要用来展示线程同步和通信的概念。在这个Java实现中,我们将深入理解这个问题的背景、原理以及如何通过Java的并发工具来解决。 生产者-消费者问题的基本...

    wait_notify_demo

    `wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用。本文将深入探讨这些方法以及如何在实际场景中应用它们。 ...

    生产者与消费者 java实现

    本主题将深入探讨生产者与消费者模型的Java实现。 生产者与消费者问题的核心是有一个共享资源(例如,一个缓冲区),生产者不断地生产产品并放入缓冲区,而消费者则从缓冲区取出产品进行消费。关键在于确保生产者...

    JAVA实现线程间同步与互斥生产者消费者问题

    4. **BlockingQueue阻塞队列**:Java的`java.util.concurrent`包提供了`BlockingQueue`接口,它是一种特殊的队列,可以在队列满时阻塞生产者,队列空时阻塞消费者,从而自动实现线程的同步和互斥。`put()`和`take()`...

    java生产者消费者

    在Java中,实现生产者消费者模式主要有两种方式:使用阻塞队列(BlockingQueue)和使用wait/notify机制。 1. 阻塞队列(BlockingQueue)实现: Java的`java.util.concurrent`包提供了多种阻塞队列实现,如...

    界面话模拟生产者消费者模式java

    - **wait()与notify()**:这是Java中最基础的线程同步机制,生产者和消费者可以通过调用对象的`wait()`方法进入等待状态,等待条件满足后再由其他线程调用`notify()`或`notifyAll()`唤醒。 4. **界面设计**: - *...

    Java 同步锁 wait notify 学习心得

    例如,在生产者-消费者模型中,生产者线程在向共享缓冲区添加元素时可能会调用`wait()`,直到有空闲空间可用。消费者线程在移除元素后会调用`notify()`或`notifyAll()`来唤醒一个或所有等待的生产者线程,告知它们...

    java生产者消费者模式

    在Java中,使用wait() / notify()方法实现生产者消费者模式的一般步骤: 1. 定义共享资源,通常是一个容器,如上述代码中的LinkedList。 2. 使用synchronized关键字创建同步代码块,确保同一时间只有一个线程能访问...

Global site tag (gtag.js) - Google Analytics