java Condition条件变量的通俗易懂解释、基本使用及注意点
最近在看pthread方面的书,看到条件变量一节的时候,回忆了下java中条件变量的使用方式。
如下:public class TestConditon
public static void main(String[] args) {
        // 创建并发访问的账户
        MyCount myCount = new MyCount("95599200901215522", 10000);
        // 创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(3); #假设改成2会怎么样??
        Thread t1 = new SaveThread("张三", myCount, 1000);
        Thread t2 = new SaveThread("李四", myCount, 1000);
        Thread t3 = new DrawThread("王五", myCount, 12600);
        Thread t4 = new SaveThread("老张", myCount, 600);
        Thread t5 = new DrawThread("老牛", myCount, 1300);
        Thread t6 = new DrawThread("胖子", myCount, 800);
        Thread t7 = new SaveThread("测试", myCount, 2100);
        // 执行各个线程
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        pool.execute(t6);
        pool.execute(t7);
        // 关闭线程池
        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 {
            while (cash - x < 0) {
                _draw.await(); // 阻塞取款操作, await之后就隐示自动释放了lock,直到被唤醒自动获取
                System.out.println(name + "阻塞中");
            }
            {
                cash -= x; // 取款
                System.out.println(name + "取款" + x + ",当前余额为" + cash);
            }
            _save.signalAll(); // 唤醒所有存款操作
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}
需要注意的是,在共用一个线程池的设计中,特别要注意饿死现象(就像上下高速如果公用车道的话,万一进入的10车全部占坑了,高速里面又满了的话,想出的都出不来,进的进不去,就出现饿死现象了),如果有大量的消费者使得生产者线程无法再运行的话,就会出现该问题,在上述例子中,将线程池数量从3改成2就可以多次测试中发现程序hang了。
所以,我们可以看到典型的在RDBMS系统中都是各种线程各司其职。
详细接口用法可参考javadoc如下:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html
java Condition条件变量的通俗易懂解释、基本使用及注意点的更多相关文章
- Condition条件变量
		条件变量是一种比较复杂的线程同步机制 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 条件变量,线程间通信提供的另一种 ... 
- Java 23种设计模式  (通俗易懂解释收集整理)
		(补充中...) P02 抽象工程模式 P14 TemplateMethod 模板方法模式 讲清楚了为什么叫做模板方法 http://www.cnblogs.com/java-my-life/arc ... 
- 深入浅出 Java Concurrency (9): 锁机制 part 4 锁释放与条件变量 (Lock.unlock And Condition)
		本小节介绍锁释放Lock.unlock(). Release/TryRelease unlock操作实际上就调用了AQS的release操作,释放持有的锁. public final boolean ... 
- (转)Java线程:新特征-条件变量
		Java线程:新特征-条件变量 条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量.但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往 ... 
- Linux多线程实践(8) --Posix条件变量解决生产者消费者问题
		Posix条件变量 int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr); int pthread_co ... 
- 27 python 初学(信号量、条件变量、同步条件、队列)
		参考博客: www.cnblogs.com/yuanchenqi/articles/5733873.html semaphore 信号量: condition 条件变量: event 同步条件:条件 ... 
- [development][C] 条件变量(condition variables)的应用场景是什么
		产生这个问题的起因是这样的: [:] <tong> lilydjwg: 主线程要启动N个子线程, 一个局部变量作为把同样的参数传入每一个子线程. 子线程在开始的十行会处理完参数. ... 
- Java线程:条件变量、原子量、线程池等
		一.条件变量 条件变量实现了java.util.concurrent.locks.Condition接口,条件变量的实例化就是通过一个Lock对象上调用newCondition()方法获得的,这样条件 ... 
- 转: 【Java并发编程】之二十:并发新特性—Lock锁和条件变量(含代码)
		简单使用Lock锁 Java5中引入了新的锁机制--Java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作.Lock接 ... 
随机推荐
- Hybrid设计--账号体系的建设
			前后端分离:开发效率高,没有SEO 现在是重客户端设计:交互和业务逻辑是前端来写,适合做前后端分离.对前端更友好,提高了效率. 传统模式开发:整个业务逻辑是server端写,不适合做前后端分离.ser ... 
- visual studio Lua 调试
			BabeLua是一款基于VS (简称VS)的免费开源的Lua集成开发环境,在Lua编辑和调试方面,具有如下功能和特性: ●Lua语法高亮 ●语法检查 ●自动补全 ●一键注释 ●格式化代码 ●自定义代码 ... 
- Python解决乱码问题
			解决python乱码问题 字符串在python的内部采用unicode的编码方式,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode ... 
- ASP.Net Core 2.2 MVC入门到基本使用系列 (一)(转)
			本教程会对基本的.Net Core 进行一个大概的且不会太深入的讲解, 在您看完本系列之后, 能基本甚至熟练的使用.Net Core进行Web开发, 感受到.Net Core的魅力. 本教程知识点大体 ... 
- InstallShield 读注册表函数 RegDBGetKeyValueEx ()执行失败
			注: rtn = RegDBGetKeyValueEx(szKey, szNumName, nvType, svNumValue, nvSize); 调用失败如果这个函数的几个参数没有初始化的值,调用 ... 
- “0x00,0x08”两个十六进制字符串,转换为整形
			int m_length=0;char buf[2]=={0x00,0x08};memcpy(&m_length,&buf[0],2); m_length=m_length<&l ... 
- IIS 8.0 Using ASP.NET 3.5 and ASP.NET 4.5微软官方安装指导
			from:https://www.iis.net/learn/get-started/whats-new-in-iis-8/iis-80-using-aspnet-35-and-aspnet-45 S ... 
- report源码分析——宏的执行
			uvm_info,uvm_error其实是对uvm_report_info,uvm_report_error的封装. 其中warning,error,fatal,macros默认都是定义为UVM_NO ... 
- [4]传奇3服务器源码分析一 SelGate
			1. 2 留存 服务端下载地址: 点击这里 
- C++/Java线程之分
			JAVA线程状态图 1.C++/windows中主线程结束,其他线程必然死亡(即使调用pthread_detach解除父子关系,主线程消亡时也会导致子线程被迫关闭). ----1.1 一个进程中可以有 ... 
