package 线程;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* jdk 1.5 版本后 利用 lock 和 condition 解决生产者和消费者问题
* Lock 接口的实现子类 就相当于 sychronized 的方法或代码块 使同时只能有一个线程反问,
* Lock 是 显示的 加锁和解锁,还允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,避免了死锁
* condition 类 就是 synchronized 中的那个具有锁功能的对象 ,
* condition 可以有多个 ,组着这与 lock 使用
* 但是 一个 condition 的 await(等待)方法只能被他自己的 signal 和 signalAll 方法唤醒
* 当 线程 A 调用了 一个 condition 对象 C 的 await 方法时 相当于持有了这个 condition 的锁,
* 只有别的线程 B 调用 condition 对象C 的 signal 和 signalAll 方法才可唤醒 线程A
*
*/
public class ProducerAndConsumer2 {
public static void main(String[] args) {
EggBox2 eb = new EggBox2(9);
Producers2 p = new Producers2(eb);
Producers2 p1 = new Producers2(eb);
Consumers2 c = new Consumers2(eb);
Consumers2 c1 = new Consumers2(eb);
new Thread(p).start();
new Thread(p1).start();
new Thread(c).start();
new Thread(c1).start();
}
}
class Egg2 {
public int id;
public Egg2(int id) {
this.id = id;
}
}
class EggBox2 {
private Lock lock = new ReentrantLock();
private Condition condition_pro = lock.newCondition(); // 生产者的锁
private Condition condition_con = lock.newCondition();// 消费者的锁
public EggBox2(int size) {
eggs = new Egg2[size];
}
int num = 0;
private Egg2[] eggs;
public int getSize() {
return eggs.length;
}
public void push(Egg2 g) {
lock.lock(); // 手动给该方法加锁 需要在方法最后边解锁
try {
while (num >= eggs.length) {
try {
condition_pro.await();// 使 消费者线程 在 condition_pro上等待
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
eggs[num++] = g;
System.out.println("the producer make egg --total--" + num);
condition_con.signal (); // 唤醒在 condition_con 上等待的所有线程
} finally {
lock.unlock(); // 解锁
}
}
public Egg2 pop() {
lock.lock();
try {
while (num <= 0) {
try {
condition_con.await(); // 使 消费者线程 在 condition_con上等待
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Egg2 egg = eggs[--num];
System.out.println("the consumer eat the egg-------total---" + num);
condition_pro.signal (); // 唤醒在 condition_pro 上等待的所有线程
return egg;
} finally {
lock.unlock();
}
}
}
class Producers2 implements Runnable {
private EggBox2 eb;
public Producers2(EggBox2 eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
eb.push(new Egg2(i));
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumers2 implements Runnable {
private EggBox2 eb;
public Consumers2(EggBox2 eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Egg2 egg = eb.pop();
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* jdk 1.5 版本后 利用 lock 和 condition 解决生产者和消费者问题
* Lock 接口的实现子类 就相当于 sychronized 的方法或代码块 使同时只能有一个线程反问,
* Lock 是 显示的 加锁和解锁,还允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁,避免了死锁
* condition 类 就是 synchronized 中的那个具有锁功能的对象 ,
* condition 可以有多个 ,组着这与 lock 使用
* 但是 一个 condition 的 await(等待)方法只能被他自己的 signal 和 signalAll 方法唤醒
* 当 线程 A 调用了 一个 condition 对象 C 的 await 方法时 相当于持有了这个 condition 的锁,
* 只有别的线程 B 调用 condition 对象C 的 signal 和 signalAll 方法才可唤醒 线程A
*
*/
public class ProducerAndConsumer2 {
public static void main(String[] args) {
EggBox2 eb = new EggBox2(9);
Producers2 p = new Producers2(eb);
Producers2 p1 = new Producers2(eb);
Consumers2 c = new Consumers2(eb);
Consumers2 c1 = new Consumers2(eb);
new Thread(p).start();
new Thread(p1).start();
new Thread(c).start();
new Thread(c1).start();
}
}
class Egg2 {
public int id;
public Egg2(int id) {
this.id = id;
}
}
class EggBox2 {
private Lock lock = new ReentrantLock();
private Condition condition_pro = lock.newCondition(); // 生产者的锁
private Condition condition_con = lock.newCondition();// 消费者的锁
public EggBox2(int size) {
eggs = new Egg2[size];
}
int num = 0;
private Egg2[] eggs;
public int getSize() {
return eggs.length;
}
public void push(Egg2 g) {
lock.lock(); // 手动给该方法加锁 需要在方法最后边解锁
try {
while (num >= eggs.length) {
try {
condition_pro.await();// 使 消费者线程 在 condition_pro上等待
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
eggs[num++] = g;
System.out.println("the producer make egg --total--" + num);
condition_con.signal (); // 唤醒在 condition_con 上等待的所有线程
} finally {
lock.unlock(); // 解锁
}
}
public Egg2 pop() {
lock.lock();
try {
while (num <= 0) {
try {
condition_con.await(); // 使 消费者线程 在 condition_con上等待
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Egg2 egg = eggs[--num];
System.out.println("the consumer eat the egg-------total---" + num);
condition_pro.signal (); // 唤醒在 condition_pro 上等待的所有线程
return egg;
} finally {
lock.unlock();
}
}
}
class Producers2 implements Runnable {
private EggBox2 eb;
public Producers2(EggBox2 eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
eb.push(new Egg2(i));
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumers2 implements Runnable {
private EggBox2 eb;
public Consumers2(EggBox2 eb) {
this.eb = eb;
}
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
Egg2 egg = eb.pop();
try {
Thread.sleep((int) Math.random() * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}