java 線程間通信,多生產者多消費者問題
/**
* 多生產者,多消費者的問題
* if判斷標記,只判斷一次,會導致不該 運行的線程運行了,出現 了數據錯誤 的情況
* while判斷標記,解決了線程獲取執行權後,是否要運行
*
*
* notify:只能喚醒一個線程,如果 本方喚醒 了本方,沒有意義 ,而且 while 判斷標記 + notify會導致死鎖
* notifyAll:解決了本方線程一定會喚醒對方線程的問題
*
* jdk1.5以後將同步 和鎖封裝成了對象 ,並將操作鎖的隱式方式 定義 到了該 對象 中,
* 將隱式動作變成 了顯示 動作
*
*
*
* Lock接口:出現替代了同步代碼塊或者同步函數,將同步的隱式鎖操作變成 現實鎖操作
* 同時更爲靈活,可以一個鎖上加上多組監視器
* lock():獲取鎖
* unlock():釋放鎖,通常需要定義finally代碼塊中
*
* Condition接口:出現 替代 了Object中的wait notify notifyAll方法
* 將這些監視器方法單獨進行了封裝,變成 Condition監視器對象
* 可以任意鎖進行組合
* await();signal();signlAll()
*/
class Resource{
private String name;
private int count = 1;
private boolean flag;
//創建一個鎖對象
Lock lock = new ReentrantLock();
//通過已有的鎖獲取該鎖上的監視器對象
Condition condition = lock.newCondition();
//通過 已有的鎖獲取兩組監視器,一級監視生產者,一組監視消費者
Condition pro_con = lock.newCondition();
Condition consumer_con = lock.newCondition();
public void set3(String name){
lock.lock();
try {
while (flag){
try {
// this.wait();
// condition.await();
pro_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
flag = true;
// notifyAll();
// condition.signalAll();
consumer_con.signal();
}finally {
lock.unlock();
}
}
public synchronized void out3(){
lock.lock();
try {
while (!flag){
try {
// this.wait();
// condition.await();
consumer_con.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
flag = false;
// notifyAll();
// condition.signalAll();
pro_con.signal();
}finally {
lock.unlock();
}
}
public void set2(String name){
lock.lock();
try {
// if (flag) 這裏以前用的是if,會發生安全問題
while (flag){
try {
// this.wait(); 第一次的用法
condition.await();
// pro_con.await();第三次的用法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
flag = true;
// notifyAll();第一次的用法
// condition.signalAll();第三次的用法
consumer_con.signal();
}finally {
lock.unlock();
}
}
public synchronized void out2(){
lock.lock();
try {
while (!flag){
try {
// this.wait();第一次的用法
condition.await();
// consumer_con.await();第三次的用法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
flag = false;
// notifyAll();
// condition.signalAll();
pro_con.signal();
}finally {
lock.unlock();
}
}
public synchronized void set(String name){
// if (flag) 這裏以前用的是if,會發生安全問題
while (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name+count;
count++;
System.out.println(Thread.currentThread().getName()+"..生產者..."+this.name);
flag = true;
notifyAll();
}
public synchronized void out(){
while (!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+".......消費者........"+this.name);
flag = false;
notifyAll();
}
}
class prodeucer implements Runnable{
private Resource resource;
public prodeucer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true){
resource.set("烤鴨");
}
}
}
class consumer implements Runnable{
private Resource resource;
public consumer(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while (true) {
resource.out();
}
}
}
public class ProducerConsumerDemo {
public static void main(String[] args){
Resource resource = new Resource();
prodeucer prodeucer = new prodeucer(resource);
consumer consumer = new consumer(resource);
Thread t0 = new Thread(prodeucer);
Thread t1 = new Thread(prodeucer);
Thread t2 = new Thread(consumer);
Thread t3 = new Thread(consumer);
t0.start();
t1.start();
t2.start();
t3.start();
}
}