溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

生產(chǎn)者消費者模式詳解及如何通過java代碼實現(xiàn)

發(fā)布時間:2021-10-13 15:08:58 來源:億速云 閱讀:97 作者:柒染 欄目:編程語言

生產(chǎn)者消費者模式詳解及如何通過java代碼實現(xiàn),很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

生產(chǎn)者消費者模式說明:

1.生產(chǎn)者只在倉庫未滿時進行生產(chǎn),倉庫滿時生產(chǎn)者進程被阻塞;

2.消費者只在倉庫非空時進行消費,倉庫為空時消費者進程被阻塞;

3.當消費者發(fā)現(xiàn)倉庫為空時會通知生產(chǎn)者生產(chǎn);

4.當生產(chǎn)者發(fā)現(xiàn)倉庫滿時會通知消費者消費;

實現(xiàn)的關(guān)鍵:

共享內(nèi)存中的兩個同步方法,及同步方法中wait()方法的調(diào)用,同步保證了對象只能被一個線程占用,wait保證了當線程在等待過程中釋放鎖,使得其他對象有機會獲得鎖。

在一個對象中,用synchonized聲明的方法為同步方法。Java中有一個同步模型-監(jiān)視器,負責(zé)管理線程對對象中的同步方法的訪問,它的原理是:賦予該對象唯一一把'鑰匙',當多個線程進入對象,只有取得該對象鑰匙的線程才可以訪問同步方法,其它線程在該對象中等待,直到該線程用wait()方法放棄這把鑰匙,其它等待的線程搶占該鑰匙,搶占到鑰匙的線程后才可得以執(zhí)行,而沒有取得鑰匙的線程仍被阻塞在該對象中等待。 總而言之,synchonized使得只有一個線程能進入臨界代碼區(qū)。

代碼實現(xiàn):

package com.thread;

public class ProducerConsumer {
	public static void main(String[] args) {
		ShareData sd = new ShareData();
		new Producer(sd).start();
		new Consumer(sd).start();
	}
}

class Producer extends Thread{
	
	private ShareData sd;
	public Producer(ShareData sd){
		this.sd = sd;
	}
	
	@Override
	public void run() {
		for(int i = 0; i < 20; i++){
			int product = (int)(Math.random()*1000);
			sd.setArray(product);
			try {
				Thread.sleep((int)(Math.random()*200));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Consumer extends Thread{
	private ShareData sd;
	public Consumer(ShareData sd){
		this.sd = sd;
	}
	@Override
	public void run() {
		for(int i = 0; i < 20; i++){
			sd.getArray();
			try {
				Thread.sleep((int)(Math.random()*200));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class ShareData{
	private static int shareArray[] = new int[10];
	private int count;
	private int in;
	private int out;
	
	ShareData(){
		this.count = 0;
		this.in = 0;
		this.out = 0;
	}
	
	public synchronized void setArray(int product){
		try{
			while(count >= shareArray.length){
				System.out.println("array full.");
				this.wait();
			}
			this.notify();
		}catch (Exception e) {
			e.printStackTrace();
		}
		shareArray[in] = product;
		count++;
		System.out.println("produce: " + product);
		in = (in + 1) % shareArray.length;
	}
	
	public synchronized int getArray(){
		try{
			while(count <= 0){
				System.out.println("array empty.");
				this.wait();
			}
			this.notify();
		}catch(Exception e){
			e.printStackTrace();
		}
		int consume = shareArray[out];
		count--;
		System.out.println("consume: " + consume);
		out = (out + 1) % shareArray.length;
		notify();
		return consume;
	}
}

輸出代碼(每次都不同):

array empty.
produce: 86
consume: 86
array empty.
produce: 232
consume: 232
array empty.
produce: 438
consume: 438
produce: 272
consume: 272
array empty.
produce: 495
consume: 495
produce: 354
produce: 533
consume: 354
produce: 92
consume: 533
produce: 374
consume: 92
produce: 441
produce: 141
consume: 374
consume: 441
consume: 141
array empty.
produce: 68
consume: 68
produce: 978
consume: 978
array empty.
produce: 737
consume: 737
array empty.
produce: 904
consume: 904
array empty.
produce: 613
consume: 613
array empty.
produce: 812
consume: 812
produce: 726
produce: 326
consume: 726
produce: 305
consume: 326
consume: 305

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI