jdk线程的生产者消费者问题
同步代码块实现生产者消费者模式
class Person {
private String name;
private String sex;
private Boolean isEmpty = Boolean.TRUE; // 表示存储区域是否为空
//生产
public void set(String name, String sex) {
synchronized (this) {
// if(isEmpty)
while (!isEmpty.equals(Boolean.TRUE)) {
// 区域不为空,此时生产者应该停下来,等着消费者消费
try {this.wait();// 等待 消费者消费} catch (InterruptedException e) {}
}
this.name = name;
try {Thread.sleep(1); } catch (InterruptedException e) {e.printStackTrace();}
this.sex = sex;
// 生产者生产之后,应该修改存储区域的状态
isEmpty = Boolean.FALSE;// 不为空
this.notifyAll();// 唤醒消费者,起来吃东西了
}
}
//消费
public void get() {
synchronized (this) {
// 存储区域为空
while (!isEmpty.equals(Boolean.FALSE)) {
try {this.wait();// 等着生产者去生产} catch (InterruptedException e) {}
}
String name = getName();
String sex = getSex();
System.out.println(name + " --> " + sex);
// 消费完成,应该修改存储区域的状态
isEmpty = Boolean.TRUE;// 空了
this.notifyAll();// 唤醒生产者,
}
}
getter/setter
}
//生产者
class Producer implements Runnable {
private Person p;
public Producer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
p.set("春哥哥", "男");
} else {
p.set("著姐", "女");
}
}
}
}
//消费者
class Consumer implements Runnable {
private Person p;
public Consumer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
p.get();
}
}
}
public class Producer_ConsumerDemo {
public static void main(String[] args) {
Person p = new Person();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
}
}
同步方法实现生产者消费者模式
class Person {
private String name;
private String sex;
private Boolean isEmpty = Boolean.TRUE; // 表示存储区域是否为空
//生产
public synchronized void set(String name, String sex) {
// if(isEmpty)
while (!isEmpty.equals(Boolean.TRUE)) {
// 区域不为空,此时生产者应该停下来,等着消费者消费
try {this.wait();// 等待 消费者消费} catch (InterruptedException e) {}
}
this.name = name;
try {Thread.sleep(1); } catch (InterruptedException e) {}
this.sex = sex;
// 生产者生产之后,应该修改存储区域的状态
isEmpty = Boolean.FALSE;// 不为空
this.notifyAll();// 唤醒消费者,起来吃东西了
}
//消费
public synchronized void get() {
// 存储区域为空
while (!isEmpty.equals(Boolean.FALSE)) {
try {this.wait();// 等着生产者去生产} catch (InterruptedException e) {}
}
String name = getName();
String sex = getSex();
System.out.println(name + " --> " + sex);
// 消费完成,应该修改存储区域的状态
isEmpty = Boolean.TRUE;// 空了
this.notifyAll();// 唤醒生产者,
}
getter/setter
}
//生产者
class Producer implements Runnable {
private Person p;
public Producer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
p.set("春哥哥", "男");
} else {
p.set("著姐", "女");
}
}
}
}
class Consumer implements Runnable {
private Person p;
public Consumer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
p.get();
}
}
}
public class Producer_ConsumerDemo {
public static void main(String[] args) {
Person p = new Person();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
}
}
可重入锁实现生产者消费者模式
jkd1.5后的另一种同步机制:通过显示定义同步锁对象来实现同步,这种机制,同步锁应该使用Lock对象充当;
在实现线程安全控制中,通常使用ReentrantLock(可重入锁)。使用该对象可以显示地加锁和解锁;
具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。
格式:
public class X {
private final ReentrantLock lock = new ReentrantLock();
//定义需要保证线程安全的方法
public void m(){
lock.lock();//加锁
try{
//... method body
}finally{
lock.unlock();//在finally释放锁
}
}
}
可重入锁没有同步监听对象,咋办呢?
Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。
class Person {
private final ReentrantLock lock = new ReentrantLock();// 创建可重入锁对象
private final Condition con = lock.newCondition();
private String name;
private String sex;
private Boolean isEmpty = Boolean.TRUE; // 表示存储区域是否为空
//生产
public void set(String name, String sex) {
lock.lock();
while(!isEmpty.equals(Boolean.TRUE)){ //表示不空状态
try {con.await();} catch (InterruptedException e) {}}
try {
this.name = name;
Thread.sleep(1);
this.sex = sex;
isEmpty = Boolean.FALSE;
con.signal();
} catch (InterruptedException e) {} finally {
lock.unlock();
}
}
//消费
public void get() {
lock.lock();
while(!isEmpty.equals(Boolean.FALSE)){ //存储区域为空,消费者应该等着
try {
con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
String name = getName();
String sex = getSex();
System.out.println(name + " --> " + sex);
//
isEmpty = Boolean.TRUE;
con.signal();
} finally {
lock.unlock();
}
}
getter/setter
}
//生产者
class Producer implements Runnable {
private Person p;
public Producer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
p.set("春哥哥", "男");
} else {
p.set("著姐", "女");
}
}
}
}
class Consumer implements Runnable {
private Person p;
public Consumer(Person p) {
this.p = p;
}
public void run() {
for (int i = 0; i < 100; i++) {
p.get();
}
}
}
public class Producer_ConsumerDemo {
public static void main(String[] args) {
Person p = new Person();
new Thread(new Producer(p)).start();
new Thread(new Consumer(p)).start();
}
}
同步代码块方式改写卖票程序
class MyRunnable implements Runnable {
private Integer num = 50;
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
private Object o = new Object();
public void sale() {
// synchronized (this) {
// synchronized (MyRunnable.class) {
synchronized (o) {
if (num > 0) {
try {Thread.sleep(1); } catch (InterruptedException e) {}
System.out.println(Thread.currentThread().getName() + "卖出第"
+ num-- + "张");
}
}
}
}
public class TicketDemoSyncByBlock {
public static void main(String[] args) {
Runnable target = new MyRunnable();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}
实现Runnable接口的方式,使用同步代码块的方式进行同步。
可以取的同步监听对象为:this、当前方法所在类的Class对象、任一不变对象;
同步方法方式改写卖票程序
class MyRunnable implements Runnable {
private Integer num = 50;
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
synchronized public void sale() {
if (num > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出第" + num-- + "张");
}
}
}
public class TicketDemoSyncByMethod {
public static void main(String[] args) {
Runnable target = new MyRunnable();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}
可重入锁方式改写卖票程序
class MyRunnable implements Runnable {
private final ReentrantLock lock = new ReentrantLock();
private Integer num = 50;
public void run() {
for (int i = 0; i < 200; i++) {
sale();
}
}
public void sale() {
lock.lock();
try {
if (num > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出第"
+ num-- + "张");
}
} finally {
lock.unlock();
}
}
}
public class TicketDemoSyncByReentrantLock {
public static void main(String[] args) {
Runnable target = new MyRunnable();
new Thread(target, "A").start();
new Thread(target, "B").start();
new Thread(target, "C").start();
}
}
jdk线程的生产者消费者问题的更多相关文章
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...
- Java如何使用线程解决生产者消费者问题?
在Java编程中,如何使用线程解决生产者消费者问题? 以下示例演示如何使用线程解决生产者消费者问题. package com.yiibai; public class ProducerConsumer ...
- Java多线程-同步:synchronized 和线程通信:生产者消费者模式
大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...
- java线程之生产者消费者
看了毕向东老师的生产者消费者,就照着视频参考运行了一下,感觉还好 这个值得学习的是条理特别清晰: ProducterConsumerDemo.java中,一个资源类Resources,生产者消费者都可 ...
- 线程锁,threadinglocal,线程池,生产者消费者模型
1.线程锁 1.锁Lock(只能锁一次) import threading import time v = [] lock = threading.Lock() def func(arg): lock ...
- Java线程通信-生产者消费者问题
线程通信示例——生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有 ...
- Java 线程池 +生产者消费者+MySQL读取300 万条数据
1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解 ...
- Python自动化--语言基础7--操作日志、加密、发送邮件、线程、生产者消费者
1.操作日志 logging.basicConfig:日志的统一处理器,对日志的输出格式和方式做配置日志级别等级CRITICAL > ERROR > WARNING > INFO & ...
随机推荐
- MSCRM Plugin Debug
MS CRM 2011的自定义和开发(11)——插件(plugin)开发(四) 上面几篇文章介绍了Microsoft Dynamics CRM 2011中如何进行插件开发,本文将介绍插件的调试. 调试 ...
- nova分析(10)—— nova-rootwrap
一.nova-rootwrap的作用 部署玩过openstack的都应该知道,它会生成一个nova用户来管理所有服务.nova身份在linux中属于普通用户级别,避免了一些需要root身份运行的操作, ...
- ios外包公司—北京动点软件分享:IOS工程自动打包并发布脚本实现
前言 IOS的开发过程中,当需要给测试人员发布测试包的时候,直接使用xcode来做的效率是非常低下的.尤其是当有一点小改动需要重新出包时,那简直是个折磨的人的工作.通过一番研究后,遂决定写一系列脚本, ...
- Hadoop:使用原生python编写MapReduce
功能实现 功能:统计文本文件中所有单词出现的频率功能. 下面是要统计的文本文件 [/root/hadooptest/input.txt] foo foo quux labs foo bar quux ...
- grep,sed,cut,awk,join个性特点
grep 从数据文件中查询/提取出含有特定关键字的行. sed 主要用于对数据文件中特定字符串的替换处理. cut 按照指定的分隔符(-d)剪下选定的列(-f num)或者字符(-c)的内容. awk ...
- .NET简谈构件系统开发模式
转自[王清培] http://www.cnblogs.com/wangiqngpei557/archive/2011/06/14/2080416.html 在本人的“.NET简谈插件系统开发模式”一文 ...
- svn 批量更新 bat脚本
由于有多个程序放在svn上管理,每天都要进入相应的目录进行svn 更新操作,现在写了一个简单的脚本进行批量自动更新. Code@echo off @echo ********************* ...
- kafka模拟客户端发送、接受消息
producer 消息的生成者,即发布消息 consumer 消息的消费者,即订阅消息 broker Kafka以集群的方式运行,可以由一个或多个服务组成,服务即broker zook ...
- NYOJ16 矩形嵌套(DAG最长路)
矩形嵌套 紫书P262 这是有向无环图DAG(Directed Acyclic Graph)上的动态规划,是DAG最长路问题 [题目链接]NYOJ16-矩形嵌套 [题目类型]DAG上的dp & ...
- Linux命令(16)压缩,解压文件
tar: 简介:tar命令只是把目录打包成一个归档(文件),并不负责压缩.在tar命令中可以带参数调用gzip或bzip2压缩.因为gzip和bzip2只能压缩单个文件. 在linux下是不需要后缀名 ...