(转)Java线程:新特征-条件变量
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Java线程:条件变量
*
* @author leizhimin 2009-11-5 10:57:29
*/
public class Test {
public static void main(String[] args) {
//创建并发访问的账户
MyCount myCount = new MyCount("95599200901215522", 10000);
//创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
Thread t1 = new SaveThread("张三", myCount, 2000);
Thread t2 = new SaveThread("李四", myCount, 3600);
Thread t3 = new DrawThread("王五", myCount, 2700);
Thread t4 = new SaveThread("老张", myCount, 600);
Thread t5 = new DrawThread("老牛", myCount, 1300);
Thread t6 = new DrawThread("胖子", myCount, 800);
//执行各个线程
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
//关闭线程池
pool.shutdown();
}
}
/**
* 存款线程类
*/
class SaveThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
SaveThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.saving(x, name);
}
}
/**
* 取款线程类
*/
class DrawThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
DrawThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.drawing(x, name);
}
}
/**
* 普通银行账户,不可透支
*/
class MyCount {
private String oid; //账号
private int cash; //账户余额
private Lock lock = new ReentrantLock(); //账户锁
private Condition _save = lock.newCondition(); //存款条件
private Condition _draw = lock.newCondition(); //取款条件
MyCount(String oid, int cash) {
this.oid = oid;
this.cash = cash;
}
/**
* 存款
*
* @param x 操作金额
* @param name 操作人
*/
public void saving(int x, String name) {
lock.lock(); //获取锁
if (x > 0) {
cash += x; //存款
System.out.println(name + "存款" + x + ",当前余额为" + cash);
}
_draw.signalAll(); //唤醒所有等待线程。
lock.unlock(); //释放锁
}
/**
* 取款
*
* @param x 操作金额
* @param name 操作人
*/
public void drawing(int x, String name) {
lock.lock(); //获取锁
try {
if (cash - x < 0) {
_draw.await(); //阻塞取款操作
} else {
cash -= x; //取款
System.out.println(name + "取款" + x + ",当前余额为" + cash);
}
_save.signalAll(); //唤醒所有存款操作
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //释放锁
}
}
}
张三存款2000,当前余额为15600
老张存款600,当前余额为16200
老牛取款1300,当前余额为14900
胖子取款800,当前余额为14100
王五取款2700,当前余额为11400
Process finished with exit code 0
import java.util.concurrent.Executors;
/**
* Java线程:不用条件变量
*
* @author leizhimin 2009-11-5 10:57:29
*/
public class Test {
public static void main(String[] args) {
//创建并发访问的账户
MyCount myCount = new MyCount("95599200901215522", 10000);
//创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
Thread t1 = new SaveThread("张三", myCount, 2000);
Thread t2 = new SaveThread("李四", myCount, 3600);
Thread t3 = new DrawThread("王五", myCount, 2700);
Thread t4 = new SaveThread("老张", myCount, 600);
Thread t5 = new DrawThread("老牛", myCount, 1300);
Thread t6 = new DrawThread("胖子", myCount, 800);
//执行各个线程
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
//关闭线程池
pool.shutdown();
}
}
/**
* 存款线程类
*/
class SaveThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
SaveThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.saving(x, name);
}
}
/**
* 取款线程类
*/
class DrawThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
DrawThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.drawing(x, name);
}
}
/**
* 普通银行账户,不可透支
*/
class MyCount {
private String oid; //账号
private int cash; //账户余额
MyCount(String oid, int cash) {
this.oid = oid;
this.cash = cash;
}
/**
* 存款
*
* @param x 操作金额
* @param name 操作人
*/
public synchronized void saving(int x,
String name) {
if (x > 0) {
cash += x; //存款
System.out.println(name + "存款" + x + ",当前余额为" + cash);
}
notifyAll(); //唤醒所有等待线程。
}
/**
* 取款
*
* @param x 操作金额
* @param name 操作人
*/
public synchronized void drawing(int x,
String name) {
if (cash - x < 0) {
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
cash -= x; //取款
System.out.println(name + "取款" + x + ",当前余额为" + cash);
}
notifyAll(); //唤醒所有存款操作
}
}
王五取款2700,当前余额为10900
老张存款600,当前余额为11500
老牛取款1300,当前余额为10200
胖子取款800,当前余额为9400
张三存款2000,当前余额为11400
Process finished with exit code 0
import java.util.concurrent.Executors;
/**
* Java线程:改为同步代码块
*
* @author leizhimin 2009-11-5 10:57:29
*/
public class Test {
public static void main(String[] args) {
//创建并发访问的账户
MyCount myCount = new MyCount("95599200901215522", 10000);
//创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
Thread t1 = new SaveThread("张三", myCount, 2000);
Thread t2 = new SaveThread("李四", myCount, 3600);
Thread t3 = new DrawThread("王五", myCount, 2700);
Thread t4 = new SaveThread("老张", myCount, 600);
Thread t5 = new DrawThread("老牛", myCount, 1300);
Thread t6 = new DrawThread("胖子", myCount, 800);
//执行各个线程
pool.execute(t1);
pool.execute(t2);
pool.execute(t3);
pool.execute(t4);
pool.execute(t5);
pool.execute(t6);
//关闭线程池
pool.shutdown();
}
}
/**
* 存款线程类
*/
class SaveThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
SaveThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.saving(x, name);
}
}
/**
* 取款线程类
*/
class DrawThread extends Thread {
private String name; //操作人
private MyCount myCount; //账户
private int x; //存款金额
DrawThread(String name, MyCount myCount, int x) {
this.name = name;
this.myCount = myCount;
this.x = x;
}
public void run() {
myCount.drawing(x, name);
}
}
/**
* 普通银行账户,不可透支
*/
class MyCount {
private String oid; //账号
private int cash; //账户余额
MyCount(String oid, int cash) {
this.oid = oid;
this.cash = cash;
}
/**
* 存款
*
* @param x 操作金额
* @param name 操作人
*/
public void saving(int x, String name) {
if (x > 0) {
synchronized (this) {
cash += x; //存款
System.out.println(name + "存款" + x + ",当前余额为" + cash);
notifyAll(); //唤醒所有等待线程。
}
}
}
/**
* 取款
*
* @param x 操作金额
* @param name 操作人
*/
public synchronized void drawing(int x,
String name) {
synchronized (this) {
if (cash - x < 0) {
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
cash -= x; //取款
System.out.println(name + "取款" + x + ",当前余额为" + cash);
}
}
notifyAll(); //唤醒所有存款操作
}
}
王五取款2700,当前余额为10900
老张存款600,当前余额为11500
老牛取款1300,当前余额为10200
胖子取款800,当前余额为9400
张三存款2000,当前余额为11400
Process finished with exit code 0
(转)Java线程:新特征-条件变量的更多相关文章
- Java线程新特征——Java并发库
一.线程池 Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...
- Java多线程-新特征-阻塞队列ArrayBlockingQueue
阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素 ...
- Linux线程同步:条件变量
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...
- 线程同步,条件变量pthread_cond_wait
与互斥锁不同,条件变量是用来等待而不是用来上锁的.条件变量用来自动阻塞一个线程,直到某特殊情况发生为止.条件变量使我们可以睡眠等待某种条件出现.条件变量是利用线程间共享的全局变量进行同步的一种机制,主 ...
- (转)java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- java线程安全问题之静态变量、实例变量、局部变量
java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如 ...
- java多线程技术之条件变量
上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇 ...
- [b0034] python 归纳 (十九)_线程同步_条件变量
代码: # -*- coding: utf-8 -*- """ 学习线程同步,使用条件变量 逻辑: 生产消费者模型 一个有3个大小的产品库,一个生产者负责生产,一个消费者 ...
- linux线程同步(2)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
随机推荐
- 初始化CSS
为什么要初始化CSS? 建站老手都知道,这是为了考虑到浏览器的兼容问题,其实不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面差异.当然,初始化样式会对SEO有一定的 ...
- EF Core学习Code First
下面通过实例来学习EF Core Code First,也就是通过EF Core迁移来完成从模型生成数据库. 本实例使用EntityFrameworkCore SQLite 数据库进行介绍,大家也可以 ...
- iOS的内存分析和内存管理
iOS的内存分析和内存管理 [内存管理]一直是iOS开发中的一个重点. 本文就带你从内存分析开始一步步了解内存的占用情况,从真实的情况中领悟真正项目开发过程中的内存的使用情况. 注:本文默认你熟悉 M ...
- tr的用法
一.tr的基本功能 功能:转换.挤压或删除字符串,从标准输入接收输入,输出到标准输出基本用法:tr [options] string1 [string2] 二.例子 1.转换 $ echo " ...
- URLWRITE视图重写技术
UrlRewrite就是地址重写,用户得到的全部都是经过处理后的URL地址,类似于Apache的mod_rewrite.将我们的动态网页地址转化为静态的地址,如html.shtml,还可以隐藏网页的真 ...
- 不支持placeholder浏览器下对placeholder进行处理
if(document.createElement('input').placeholder !== '') { $('[placeholder]').focus(function() { var i ...
- php变量双击选择无法选择$符号
创建/Data/Packages/User/PHP.sublime-settings文件,内容为 { "word_separators": "./\\()\&qu ...
- python报错“UnicodeEncodeError: 'ascii' codec can't encode characters in position 22-26: ordinal not in range(128)”问题解决
方案是在python的Lib\site-packages文件夹下新建一个sitecustomize.py,内容为: # encoding=utf8 import sys reload(sys) sys ...
- seajs源码阅读
乘着周日有点时间,阅读一下玉伯大神的源码. seajs的源码写得真的很好,很是佩服,工整美观不愧是大神,造福百姓. 说起seajs不得不说,AMD和CMD的区别. CMD 推崇依赖就近,AMD 推崇 ...
- 【恢复】 Redo文件丢失的恢复
第一章 Redo文件丢失的恢复 1.1 online redolog file 丢失 联机Redo日志是Oracle数据库中比较核心的文件,当Redo日志文件异常之后,数据库就无法正常启动,而且有丢 ...