文档章节

【Java并发编程实战】– 在同步代码中使用条件

pan_1308
 pan_1308
发布于 2017/09/07 17:21
字数 622
阅读 9
收藏 0

一、概述

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

由于缓冲区是一个共享的数据结构,我们必须采用同步机制,比如 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();
	}
}

 

© 著作权归作者所有

共有 人打赏支持
pan_1308
粉丝 4
博文 95
码字总数 58819
作品 0
黄冈
私信 提问
Java面试:投行的15个多线程和并发面试题

本文由ImportNew -一杯哈希不加盐 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,...

ImportNew
08/23
0
0
Java 使用 happen-before 规则实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。按照官方的...

stateIs0
01/20
0
0
【死磕Java并发】—– 死磕 Java 并发精品合集

【死磕 Java 并发】系列是 LZ 在 2017 年写的第一个死磕系列,一直没有做一个合集,这篇博客则是将整个系列做一个概览。 先来一个总览图: 【高清图,请关注“Java技术驿站”公众号,回复:脑...

chenssy
07/22
0
0
15《Java核心技术》之synchronized和ReentrantLock有什么区别呢?

一、提出问题 从今天开始,我们将进入 Java 并发学习阶段。软件并发已经成为现代软件开发的基础能力,而 Java 精心设计的高效并发机制,正是构建大规模应用的基础之一,所以考察并发基本功也...

飞鱼说编程
11/05
0
0
java多线程系列:通过对战游戏学习CyclicBarrier

CyclicBarrier是java.util.concurrent包下面的一个工具类,字面意思是可循环使用(Cyclic)的屏障(Barrier),通过它可以实现让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一...

huangzd
01/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

day148-2018-11-15-英语流利阅读-待学习

赴美生子恐结束?特朗普中期选举憋大招 毛西 2018-11-15 1.今日导读 在 2013 年,一部《北京遇上西雅图》让赴美生子这个曾经神秘的话题吸引了很多关注。每年,数以万计的父母远赴美国,并在那...

飞鱼说编程
3分钟前
0
0
OSChina 周四乱弹 —— 每次我穿短裙的时候

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @瘟神灬念 :分享DM DOKURO的单曲《Reality Check Through The Skull》: 差点以为手机卡了 《Reality Check Through The Skull》- DM DOKURO...

小小编辑
12分钟前
9
2
Windows 10 设置 Java 环境变量

首先你需要在我的电脑中打开,找到环境变量属性。 找到环境变量属性 找到环境变量属性后单击将会看到下面的设置界面。 在这个界面中设置高级系统设置。 环境变量 在弹出的界面中选择设置环境...

honeymose
今天
2
0
用any-loader封装jQuery的XHR —— 随便写着玩系列

哎,都说没人用JQuery啦,叫你别写这个。 其实我也是好高骛远使用过npm上某个和某个很出名的XHR库,嗯,认识我的人都知道我喜欢喷JQ,以前天天喷,见面第一句,你还用JQ,赶紧丢了吧。但我也...

曾建凯
今天
8
0
SLF4J的正确打开方式

最近公司好几波人过来问日志打印相关的异常,大多是jar包冲突引起的,发现大部分同事不太清楚各种日志框架以及相关jar包之间的关系,所以今天详细的讲解下常见jar包之间的关系,以及如何正确...

lexus90
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部