目錄
生產消費模型基本概念
問題描述
解決方法
wait()
notify()
notifyAll()
具體例子
生產者類:
消費者類:
商品類:
測驗類:
ProductionConsumptionFinal
生產消費模型基本概念
生產消費模型就是通過一個容器來解決生產者與消費者之間的強耦合問題,我們大家都去超市消費過,我們作為消費者,在不斷的消費,而是超市就是那個生產者,我們與超市之間存在的所謂容器其實就是貨架,當貨架空的時候,我們作為消費者就不能在消費了,當貨架滿的時候,超市作為生產者就不能在生產了,
問題描述
生產與消費的速度不匹配
解決方法
wait()
會讓執行該方法的當前的執行緒進入等待狀態

舉個例子:
public class TestWait implements Runnable{
private final Object object = new Object();
@Override
public void run() {
synchronized (object){
System.out.println("執行緒執行開始.....");
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("執行緒執行結束.....");
}
}
public static void main(String[] args){
TestWait testWait = new TestWait();
Thread thread = new Thread(testWait);
thread.start();
}
}
測驗結果:

可以看出這個執行緒呼叫wait()方法之后就會進入等待狀態,一直在運行,且不會中斷,除非讓這個執行緒接受喚醒操作或者中斷操作,
notify()
喚醒被wait()的執行緒,如果有多個執行緒被wait()隨機喚醒一個

notify()呼叫后不會立即釋放鎖,而是當執行notify()的執行緒執行完成,即退出同步代碼塊才會釋放掉鎖,
舉個列子:
public class TestWait implements Runnable{
private final Object object = new Object();
public void setFlag(boolean flag){
this.flag = flag;
}
private boolean flag = true;
@Override
public void run() {
if(flag){
this.testwait();
}else {
this.testnotify();
}
}
public void testwait(){
synchronized (object){
try {
System.out.println("執行緒開始執行");
Thread.sleep(1000);
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("執行緒執行結束");
}
}
public void testnotify(){
synchronized (object){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
object.notify();
}
}
public static void main(String[] args){
TestWait testWait = new TestWait();
Thread thread = new Thread(testWait);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
testWait.setFlag(false);
Thread thread1 = new Thread(testWait);
thread1.start();
}
}
測驗結果:

notifyAll()
喚醒所有被wait()的執行緒

舉個例子:
public class TestWait implements Runnable{
private final Object object = new Object();
private boolean flag = true;
public void setFlag(boolean flag){
this.flag = flag;
}
@Override
public void run() {
if(flag){
this.testwait();
}else{
this.testnotify();
}
}
public void testwait(){
synchronized (object){
try {
System.out.println(Thread.currentThread().getName()+"執行緒開始執行");
Thread.sleep(1000);
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"執行緒執行結束");
}
}
public void testnotify(){
synchronized (object){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
object.notifyAll();
}
}
public static void main(String[] args){
TestWait testWait = new TestWait();
Thread thread = new Thread(testWait,"執行緒1");
thread.start();
Thread thread1 = new Thread(testWait,"執行緒2");
thread1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
testWait.setFlag(false);
Thread thread2 = new Thread(testWait);
thread2.start();
}
}
測驗結果:

具體例子
這個例子當中,我們會寫四個類,生產者類,消費者類,商品類,測驗類
生產者類:
/**
* 生產者類
*/
public class Producer implements Runnable{
private Goods goods;
private TestPC tp;
@Override
public void run() {
while (true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (TestPC.queue){
goods = new Goods(1,"商品");
if(TestPC.queue.size()<tp.MAX_POOL){
TestPC.queue.add(goods);
System.out.println(Thread.currentThread().getName()+"生產商品");
}else {
try {
TestPC.queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
消費者類:
/**
* 消費者類
*/
public class Consumer implements Runnable{
@Override
public void run() {
while (true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (TestPC.queue){
if(!TestPC.queue.isEmpty()){
TestPC.queue.poll();
System.out.println(Thread.currentThread().getName()+"消費商品");
}else {
TestPC.queue.notify();
}
}
}
}
}
商品類:
/**
* 商品類
*/
public class Goods {
private int id;
private String name;
public Goods(int id,String name){
this.id = id;
this.name = name;
}
}
測驗類:
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
/**
* 測驗類
*/
public class TestPC {
public static final int MAX_POOL = 10;
public static final int MAX_PRODUCER = 5;
public static final int MAX_CONSUMER = 4;
public static Queue<Goods> queue = new ArrayBlockingQueue<>(MAX_POOL);
public static void main(String[] args){
Producer producer = new Producer();
Consumer consumer = new Consumer();
for(int i = 0;i<MAX_PRODUCER;i++){
Thread threadA = new Thread(producer,"生產者執行緒"+i);
threadA.start();
}
for(int j = 0;j<MAX_CONSUMER;j++){
Thread threadB = new Thread(consumer,"消費者執行緒"+j);
threadB.start();
}
}
}
測驗結果:

這個可能不是那么清晰,但是原理就是這么個原理,接下來的版本可能就會比較清晰!
ProductionConsumptionFinal
public class Test1 {
private static Integer count = 0;
private static final Integer FULL = 10;
private static String LOCK = "lock";
public static void main(String[] args) {
Test1 test1 = new Test1();
new Thread(test1.new Producer()).start();
new Thread(test1.new Consumer()).start();
new Thread(test1.new Producer()).start();
new Thread(test1.new Consumer()).start();
new Thread(test1.new Producer()).start();
new Thread(test1.new Consumer()).start();
new Thread(test1.new Producer()).start();
new Thread(test1.new Consumer()).start();
}
class Producer implements Runnable{
@Override
public void run() {
for (int i = 0;i<10;i++){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK){
while (count == FULL){
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
System.out.println(Thread.currentThread().getName()+"生產者生產,目前共有"+count);
LOCK.notifyAll();
}
}
}
}
class Consumer implements Runnable{
@Override
public void run() {
for (int i = 0;i<10;i++){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (LOCK){
while(count == 0){
try {
LOCK.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
System.out.println(Thread.currentThread().getName()+"消費者消費,目前共有"+count);
LOCK.notifyAll();
}
}
}
}
}
測驗結果:

好了這就是Java中的生產消費模型,在面試中也常考的問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294627.html
標籤:其他
