(转)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)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
随机推荐
- 抓包工具 - Fiddler(详细介绍)
Fiddler的详细介绍 一.Fiddler与其他抓包工具的区别 1.Firebug虽然可以抓包,但是对于分析http请求的详细信息,不够强大.模拟http请求的功能也不够,且firebug常常是需要 ...
- 电脑上的windows键突然失灵了,肿么办
windows经常会用到,或许平时感觉不出异常来,偶尔用一次的时候,去发现失灵了,肿么办? 如果只是单纯的弹出开始菜单来,可以按Ctrl+Esc,功能是一样的. 这种情况其实是windows被禁用了, ...
- AngularJS高级程序设计读书笔记 -- 大纲篇
零. 初衷 现在 AngularJS 4 已经发布了, 楼主还停留在 1.x 的阶段, 深感自卑. 学习 AngularJS 的初衷是因为, 去年楼主开始尝试使用 Flask 开发自动化程序, 需要用 ...
- HTTP协议 URL
http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的We ...
- v9更新栏目缓存提示PHP has encountered a Stack overflow解决方法
原因: 客户在把一些栏目删除或者新增栏目时没更新栏目缓存导致v9_category表里有原来的垃圾信息,多余的表. 解决方法:通过phpmyadmin找到栏目表出错的条目,修改错误信息. 具体步骤: ...
- Vue 项目实战系列 (三)
我们继续前两节的开发.本节教程实现的效果如下: 效果很简单,但是实现起来却要用到Vue的很多知识,下面我们将一步一步的实现这个效果. 首先这些城市的信息都是从后台的server里面获取的,所以我们需要 ...
- CSS active选择器与CSS hover选择器
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- DataFrame创建
DataFrame/DataSet 创建 读文件接口 import org.apache.spark.sql.SparkSession val spark = SparkSession .builde ...
- 【Android Developers Training】 55. 序言:高效显示位图
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 关于Ext 修复源代码 bug的方法
Ext修复源代码出现的问题 1.使用override属性,重写组件 定义一个新的组件,override属性设为要重写的源组件 例子: Extjs4.2.3遇到的一个bug,Datefield 选择不了 ...