【Java并发编程实战】– 在同步代码中使用条件
博客专区 > pan_1308 的博客 > 博客详情
【Java并发编程实战】– 在同步代码中使用条件
pan_1308 发表于2个月前
【Java并发编程实战】– 在同步代码中使用条件
  • 发表于 2个月前
  • 阅读 6
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 学生专属云服务套餐 10元起购>>>   

一、概述

在并发编程中的一个经典问题是生产者与消费者问题:我们有一个数据缓冲区,一个或多个数据的生产者在缓冲区存储数据,而一个或多个数据的消费者,把数据从缓冲区取出。

由于缓冲区是一个共享的数据结构,我们必须采用同步机制,比如 synchronized 关键字来控制对它的访问。但是我们有更多的限制因素,如果缓冲区是满的,生产者不能存储数据,如果缓冲区是空的,消费者不能取出数据。

对于这些类型的情况,Java在Object对象中提供wait(),notify(),和notifyAll() 方法的实现。

 wait() 方法:

      1、只能在同步代码块中调用

      2、当一个线程调用 wait() 方法,jvm将这个线程置入休眠,并且释放控制这个同步代码快的对象,同时允许其他线程执行这个对象控制的其他同步代码块

      3、为了唤醒这个线程,必须在这个对象控制的某个同步代码快调用 notify() 方法或者 notifyAll() 方法

二、实现

import java.util.Date;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 中间缓存
 */
public class EventStorage {

	private int maxSize;
	private LinkedBlockingQueue<Date> storage;
	
	public EventStorage(int maxSize){
		this.maxSize = maxSize;
		storage = new LinkedBlockingQueue<Date>();
	}
	
	// 存放操作
	public synchronized void set(){
		// 在while循环中,你必须保持检查条件和调用wait()方法。你不能继续执行,直到这个条件为true。
		while(storage.size() == maxSize){ //循环判断 为 真,才进行 线程 挂起操作.
			try {
				wait(); // 挂起 该线程,等待 剩余空间出现
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		storage.offer(new Date());
		System.out.println("存操作- storage size:" + storage.size());
		notifyAll(); // 唤醒 所有 因为 wait() 操作而休眠的 线程.
	}
	
	// 取出操作
	public synchronized void get(){
		while(storage.size() == 0){ //循环判断 为 真,才进行 线程 挂起操作.
			try {
				wait(); // 挂起 该线程,等待 剩余空间出现
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		storage.poll();
		System.out.println("取出操作- storage size:" + storage.size());
		notifyAll(); // 唤醒 所有 因为 wait() 操作而休眠的 线程.
	}
}
import java.util.concurrent.TimeUnit;

/**
 *  生产者
 */
public class EventProducer implements Runnable{

	private EventStorage eventStorage;
	
	public EventProducer(EventStorage eventStorage){
		this.eventStorage = eventStorage;
	}
	
	@Override
	public void run() {
	   while(true){
		   eventStorage.set();
		   try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	   }
	}
}
/**
 * 消费者
 */
public class EventCustomer implements Runnable{
    
    private EventStorage eventStorage;
	
	public EventCustomer(EventStorage eventStorage){
		this.eventStorage = eventStorage;
	}

	public void run() {
		while(true){
			eventStorage.get();
			try {
				TimeUnit.SECONDS.sleep(2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
public class EventTest {

	public static void main(String[] args) {
		EventStorage eventStorage = new EventStorage(3);
		
		EventProducer producer = new EventProducer(eventStorage);
		EventCustomer customer = new EventCustomer(eventStorage);
		
		Thread threadProducer = new Thread(producer);
		Thread threadCostomer = new Thread(customer);
		
		threadProducer.start();
		threadCostomer.start();
	}
}

 

共有 人打赏支持
粉丝 5
博文 76
码字总数 56423
×
pan_1308
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: