锁使用的是ReentrantLock,为一种可重入的互斥锁
...
package com.zc.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Dept {
private int max; // 仓库大小
private int has; // 仓库已用大小
private Lock lock; // 锁
private Condition fullcondition; // 生产通知 控制生产线程
private Condition emptycondition; // 消费通知 控制消费线程
// 创建仓库
public Dept(int max) {
this.max = max;
this.has = 0;
this.lock = new ReentrantLock();
this.emptycondition = lock.newCondition();
this.fullcondition = lock.newCondition();
}
// 装入
public void put(int num) {
lock.lock();
int wanPuttNum = num; // 想要装入的数量
try {
while (wanPuttNum > 0) {
while (has == max) {
fullcondition.await(); // 仓库容量不足时,生产线程等待
System.out.println("Producers ---wait---wantput" + wanPuttNum);
}
int couldPutNum = (wanPuttNum + has > max) ? max - has : wanPuttNum; // 本次装入的数量
int endhas = has + couldPutNum; // 操作后的仓库已用容量
System.out.println(Thread.currentThread().getName() + "--wantput--" + wanPuttNum + "--couldput--" + couldPutNum + "--操作前--"
+ has + "--操作后--" + endhas);
wanPuttNum = wanPuttNum - couldPutNum; // 判断是否还要2次装入
has = endhas; // 修改已用容量
emptycondition.signalAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock(); // 解锁操作需要放入finally,避免出现死锁
}
}
public void get(int num) {
lock.lock();
int wantGetNum = num; // 期望获取的数量
try {
while (wantGetNum > 0) {
while (has == 0) {
emptycondition.await();
System.out.println("Customers ---wait--wantget" + wantGetNum);
}
int couldGetNum = (wantGetNum > has) ? has : wantGetNum; // 本次获取的数量
int endhas = has - couldGetNum; // 操作结束的已用容量
System.out.println(Thread.currentThread().getName() + "--想要获得--" + wantGetNum + "--本次获得--" + couldGetNum + "--操作前--" + has
+ "--操作后--" + endhas);
wantGetNum = wantGetNum - couldGetNum; // 判断是否需要再次请求
has = endhas; // 更新已用容量
fullcondition.signalAll(); // 通知生产线程
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
//生产者
class Producers {
private Dept dept;
public Producers(Dept dept) {
this.dept = dept;
}
public void doPut(final int num) {
new Thread() {
public void run() {
dept.put(num);
}
}.start();
}
}
class Customers {
private Dept dept;
public Customers(Dept dept) {
this.dept = dept;
}
public void doGet(final int num) {
new Thread() {
public void run() {
dept.get(num);
}
}.start();
}
}
public class Test02 {
public static void main(String[] args) {
Dept dept = new Dept(200);
Customers ce = new Customers(dept);
Producers pe = new Producers(dept);
pe.doPut(90);
ce.doGet(210);
pe.doPut(150);
ce.doGet(30);
}
}
...

感觉condition.await就相当于object.wait,condition.signal则是object.notify。condition灵活性更好,能够完成更细精度的通知
网友评论