白话 Java Condition
Condition 依赖于Lock,相当于共享单车上面锁的二维码,他维护了一个或多个
像LinkedBlockingQueue的生产者和消费者一样的队列 并发库中的BlockingQueue是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列中,如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象,
也可以叫做Lock条件,相当于三个人去骑一辆共享单车,三个人排成一个同步队列,然后第一个扫码,发现没交押金,就在旁边等,相当于unlock了,但是他放在等待队列里了,如果这时候,第二个人扫码发现也没交押金,释放锁对象unlock,他就去等待队列排队,这时候第一个人充值成功了,他就被唤醒,signal() ,他直接去扫码,扫码成功骑车走了!!!这里的是否交押金可以当做一个条件!!
package com.wangji.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyConditon {
final static Lock lock=new ReentrantLock();
final static Condition condition=lock.newCondition();//监视器上面维护一个等待队列,唤醒条件就是你是否充钱了
static boolean isopen=false;
public static void main(String[] args) {
//线程类,相当于人,给他分配个任务 ,就是去骑车扫码
class People implements Runnable{
private String id;
private boolean isyajin;//是否交押金
public People(String id,boolean isyajin) {
// TODO Auto-generated constructor stub
this.id=id;
this.isyajin=isyajin;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public boolean isIsyajin() {
return isyajin;
}
public void setIsyajin(boolean isyajin) {
this.isyajin = isyajin;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(isopen){
System.out.println("已经被骑走了!老铁");
}else{
System.out.println("试着去开锁"+id);
lock.lock();
if(isyajin){
System.out.println("我开车走了,bye!"+id);
isopen=true;
lock.unlock();
}else{
//没交押金去旁边排队
try {
System.out.println("没交押金,等待"+id);
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
System.out.println("排队去,未交押金"+id);
lock.unlock();
}
}
}
}
//人还有一个交押金的动作
public void Yajin(){
System.out.println("我去交押金"+id);
this.setIsyajin(true);
lock.lock();
//交完押金,可以去扫码了
condition.signalAll();
lock.unlock();
}
}
//用线程池进行处理,相当于摩拜单车后台
ExecutorService service=Executors.newFixedThreadPool(3);
//二个人
People p1= new People("1", false);
People p2= new People("2", false);
//开锁
service.execute(p1);
if(!p1.isIsyajin()&&!isopen){
p1.Yajin();
}
service.execute(p2);
if(!p2.isIsyajin()&&!isopen){
p2.Yajin();
}
//执行
service.shutdown();
}
}
也可以维护多个等待队列,相当于条件判断
package com.wangji.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTs {
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(); // 释放锁 }
}
}
上一篇: java iterator和Iterable的区别
下一篇: C语言的输入和输出函数