(转)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)-条件变量
一.概述 上一篇,介绍了互斥量.条件变量与互斥量不同,互斥量是防止多线程同时访问共享的互斥变量来保 ...
随机推荐
- 放大镜原生js
<!DOCTYPE html><html><head> <title></title> <style type="text/ ...
- 关于iphone点击readonly的input虚拟键盘不消失的情况
今天遇到了一个比较棘手的问题,事情是这样的: 咱有一个添加地址的页面,大概长这样: 收货地址后那个"请选择收货地址"是一个readonly的input, 咱一进页面,直接点击这个& ...
- socket套接字编程
一.概述 1.socket是一种进程间通信方式,既可以用于一台机器,也可以用于网络.常用语C/S模型. 2.可以跨越Windows和Linux操作系统,可以跨越不同语言. 3.注意网络字节序和主机字节 ...
- ui-router 父子state共享数据
如果ui-view是嵌套的,那么在子view中,可以直接引用 $scope.$parent 即可.
- 开发抓包工具 Mac charles 3.11.5 破解版 安装包
摘要 在发开过程中,追踪请求和监控请求与返回数据是我们经常会需要的一个需求,在Mac端,Charles是一款非常易用的抓包工具. 一.简介 Charles是Mac端的一款截取与分析网络请求的工具,在网 ...
- jq瀑布流代码
<style> #zh{ position:fixed; width:100%; height:100%; background:url(images/bgblack.png); top: ...
- PHP 上传文件大小限制
配置php.ini文件 (以上传500M以下大小的文件为例) 查找以下选项并修改-> file_uploads = On ;打开文件上传选项 upload_max_filesize = 500M ...
- 使用 XML 配置 MyBatis
构建 SqlSessionFactory 最常见的方式是基于 XML 配置(的构造方式).下面的 mybatis-config.xml 展示了一个 典型的 MyBatis 配置文件的样子: XML C ...
- ReactiveCocoa源码解析(三) Signal代码的基本实现
上篇博客我们详细的聊了ReactiveSwift源码中的Bag容器,详情请参见<ReactiveSwift源码解析之Bag容器>.本篇博客我们就来聊一下信号量,也就是Signal的的几种状 ...
- nvarchar 和varchar区别
有时候设计字段的时候,碰到nvarchar和varchar时候,是有点犹豫.所以今天就来探个究竟把. (一) varchar是非Unicode可变长度类型,nvarchar是Unicode编码可变长 ...