生產者生產資料到緩衝區中,消費者從緩衝區中取資料。
如果緩衝區已經滿了,則生產者執行緒阻塞;
如果緩衝區為空,那麼消費者執行緒阻塞。
1.併發性
由於方法呼叫是阻塞的,在消費者的方法沒有返回之前,生產者只好一直等在那邊。萬一消費者處理資料很慢,生產者一直等就會白白浪費資源,建立緩衝區以後,生產者把資料往緩衝區一丟,就可以再去生產下乙個資料,消費者也直接取緩衝區中的資料,不用再等待生產者生產。
2.耦合性
如果讓生產者直接呼叫消費者的某個方法,那麼生產者對於消費者就會產生依賴,兩者之間耦合性增強,所以如果兩者都依賴於某個緩衝區,兩者之間不直接依賴,耦合也就相應降低了。
緩衝區滿時,生產者休眠,直到被消費者取資料時喚醒。緩衝區為空時,消費者休眠,直到被生產者喚醒。
a執行緒為生產者放資料,
b執行緒為消費者取資料,緩衝區有乙個資料,大小也為1。
生產者和消費者併發執行,a等待
b消費資料,此時正好來了個消費者
b2把這乙個資料取走,而
b去取的時候緩衝區已經為空,
b也進行等待
a生產,a、
b互相等待發生死鎖。
所以為了避免多執行緒死鎖現象,就不能讓讀寫資料的方法同時執行。可以用
synchronized
修飾兩個普通方法,因為如果有多個普通方法被
synchronized
修飾,如果多執行緒共用乙個物件,它們是不會同時執行這些方法的。如果是不同物件,他們會同時執行自己的方法
以下三種方法中
resource
是緩衝區,所有生產者消費者執行緒都共用
resource
這個物件
通過object
類的wait()
、notify()
、notifyall()
方法配合
synchronized
關鍵字實現執行緒的等待
/通知)
public class resource else catch (interruptedexception e)
} }public synchronized void add() else catch (interruptedexception e)
} }}
public class producerthread extends thread
@override
public void run() catch (interruptedexception e)
resource.add();
}}
}
public class consumerthread extends thread
@override
public void run() catch (interruptedexception e)
resource.remove();
} }}
public class client
}
方法一其實相當於是乙個佇列,要麼放資料要麼取資料,兩個操作不會同時執行,效率低。
通過condition介面的await()、signal()、signalall()配合lock鎖實現執行緒的等待/通知機制。
1.condition介面依賴於lock介面,通過lock.newcondition()生成乙個condition並繫結到lock鎖上
2.condition的await()和signal()方法,都必須在lock保護之內,就是說必須在lock.lock()和lock.unlock之間才可以使用
1.condition
介面可以支援多個等待佇列,因為乙個
lock
例項可以繫結多個
condition
,而消費者和生產者都有各自的
condition
,從而使用者可以只在指定的等待佇列上喚醒執行緒,而不是喚醒所有的執行緒。
2.condition
介面支援等待中斷
3.condition
介面支援定時等待
public class resource
public void add() else catch (interruptedexception e)
}} finally
} public void remove() else catch (interruptedexception e)
}} finally
}}
public class producerthread extends thread
public void run() catch (interruptedexception e)
resource.add();
} }}
public class consumerthread extends thread
public void run() catch (interruptedexception e)
resource.remove();
} }}
public class client
}
通過阻塞佇列blockingqueue和它的兩個方法put()、take()方法實現
put()
:佇列未滿時,直接插入沒有返回值;佇列滿時會阻塞等待,一直等到佇列未滿時再插入。
take()
:佇列不為空返回隊首值並移除;當隊列為空時會阻塞等待,一直等到佇列不為空時再返回隊首值
public class resource catch (interruptedexception e)
}public void remove() catch (interruptedexception e) }}
public class producerthread extends thread
public void run() catch (interruptedexception e)
resource.add();
} }}
public class consumerthread extends thread
public void run() catch (interruptedexception e)
resource.remove();
} }}
public class client
}
設計模式之生產者 消費者模式
public class producerconsumer 生產者執行緒,負責生產公共資源 class producerthread implements runnable override public void run catch interruptedexception e resource....
設計模式 生產者消費者模式
常見場景 某個模組負責產生資料,這些資料由另乙個模組來負責處理。產生資料的模組,就形象地稱為生產者 而處理資料的模組,就稱為消費者。該模式還需要有乙個緩衝區處於生產者和消費者之間,作為乙個中介。生產者把資料放入緩衝區,而消費者從緩衝區取出資料 緩衝區作用 1.解耦,生產者和消費者只依賴緩衝區,而不互...
設計模式 生產者消費者模式
在併發程式設計中使用生產者和消費者模式能夠解決絕大多數併發問題。該模式通過平衡生產線程和消費執行緒的工作能力來提高程式的整體處理資料的速度。生產者消費者模式是通過乙個容器來解決生產者和消費者的強耦合問題。生產者和消費者彼此之間不直接通訊,而通過阻塞佇列來進行通訊,所以生產者生產完資料之後不用等待消費...