1. 程式人生 > >多執行緒:wait/notifyAll,實現生產者消費者

多執行緒:wait/notifyAll,實現生產者消費者

注意,一般使用notifyAll,如果使用notify,則只會通知一個wait的執行緒,notifyAll可防止通知訊號丟失 

package com.chapter1.ch1.wait;

public interface AbstractStorage {
	
	void consume(int num);
	
	void produce(int num);
	
}
package com.chapter1.ch1.wait;

import java.util.LinkedList;

public class Storage implements AbstractStorage {

	private static final int MAX_SIZE = 100;
	
	private LinkedList<Object> list = new LinkedList<Object>();
	
	
	/**
	 * 消費
	 */
	@Override
	public void consume(int num) {
		synchronized (list) {
			while (list != null && num > list.size()) {
				System.out.println("要消費【" + num + "】,但倉庫內只有" + "【" + list.size() + "】");
				
				try {
					list.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
			for (int i = 0; i < num; i++) {
				list.remove();
			}
			
			System.out.println("已要消費【" + num + "】,倉庫內剩餘" + "【" + list.size() + "】");
			
			// 通知生產方法上wait的執行緒不再wait
			list.notifyAll();
		}
	}

	@Override
	public void produce(int num) {
		synchronized (list) {
			while (list != null && (num + list.size()) > MAX_SIZE) {
				System.out.println("要生產【" + num + "】,但倉庫內已有" + "【" + list.size() + "】,生產後大於100");
				
				try {
					list.wait();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			
			for (int i = 0; i < num; i++) {
				list.add(new Object());
			}
			
			System.out.println("已生產【" + num + "】,倉庫內剩餘" + "【" + list.size() + "】");
			
			// 通知生產方法上wait的執行緒不再wait
			list.notifyAll();
		}
	}
	
}
package com.chapter1.ch1.wait;

public class Producer extends Thread {
	
	private int num;
	
	public AbstractStorage abstractStorage;
	
	public Producer(AbstractStorage abstractStorage) {
		this.abstractStorage = abstractStorage;
	}
	
	public void setNum(int num) {
		this.num = num;
	}
	
	
	public void produce(int num) {
		this.abstractStorage.produce(num);
	}
	
	
	@Override
	public void run() {
		
		produce(num);
		
	}
}
package com.chapter1.ch1.wait;

public class Consumer extends Thread {
	
	private int num;
	
	public AbstractStorage abstractStorage;
	
	public Consumer(AbstractStorage abstractStorage) {
		this.abstractStorage = abstractStorage;
	}
	
	public void setNum(int num) {
		this.num = num;
	}
	
	
	public void consumer(int num) {
		this.abstractStorage.consume(num);
	}
	
	
	@Override
	public void run() {
		
		consumer(num);
		
	}
}
package com.chapter1.ch1.wait;

public class WaitMain {
	
	
	public static void main(String[] args) {
		AbstractStorage storage = new Storage();
		
		Producer p1 = new Producer(storage);
		Producer p2 = new Producer(storage);
		Producer p3 = new Producer(storage);
		Producer p4 = new Producer(storage);
		
		p1.setNum(10);
		p2.setNum(10);
		p3.setNum(10);
		p4.setNum(80);
		
		Consumer c1 = new Consumer(storage);
		Consumer c2 = new Consumer(storage);
		Consumer c3 = new Consumer(storage);
		Consumer c4 = new Consumer(storage);
		
		c1.setNum(5);
		c2.setNum(5);
		c3.setNum(90);
		c4.setNum(1);
		
		try {
			p1.start();
			Thread.sleep(1000);
			p2.start();
			Thread.sleep(1000);
			p3.start();
			Thread.sleep(1000);
			p4.start();
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		try {
			c1.start();
			Thread.sleep(2000);
			c2.start();
			Thread.sleep(2000);
			c3.start();
			Thread.sleep(2000);
			c4.start();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	
}

相關推薦

執行wait/notifyAll實現生產者消費者

注意,一般使用notifyAll,如果使用notify,則只會通知一個wait的執行緒,notifyAll可防止通知訊號丟失  package com.chapter1.ch1.wait; publ

執行死鎖樂觀鎖悲觀鎖

死鎖: 兩個或者多個程序競爭統一資源而形成的僵持的局面,若無外力作用,將無法推進。 本質原因: 1)系統資源有限 2)程序推進順序不合理 死鎖的條件: (1)互斥。某個資源在一段時間只能有一個程序佔有,只有當使用該資源的程序釋放後,其他程序才能佔有該資源。 (2

利用執行和TCP技術實現客戶端與服務端之間的通訊

server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h>

linux執行學習(七)——實現生產者消費者

在上一篇文章中,利用訊號量實現了執行緒間的互斥,這一篇將要利用訊號量的互斥同步機制來實現一個經典例項,就是“生產者和消費者”。 1、簡單描述生產者和消費者的問題。 有一個緩衝區和兩個執行緒:生產者和消費者。生產者把產品放入緩衝區,而消費者從緩衝區中拿走。當緩衝區滿時,生產者必

Thinking in Java---執行通訊+三種方式實現生產者消費者問題

前面講過執行緒之間的同步問題;同步問題主要是為了保證對共享資源的併發訪問不會出錯,主要的思想是一次只讓一個執行緒去訪問共享資源,我們是通過加鎖的方法實現。但是有時候我們還需要安排幾個執行緒的執行次序,而在系統內部執行緒的排程是透明的,沒有辦法準確的控制執行緒的切

Java Executor併發框架(十四)Executor框架執行池使用原始方式實現生產者消費者模式

       我們可以利用wait()來讓一個執行緒在某些條件下暫停執行。例如,在生產者消費者模型中,生產者執行緒在緩衝區為滿的時候,消費者在緩衝區為空的時 候,都應該暫停執行。如果某些執行緒在等待某些條件觸發,那當那些條件為真時,你可以用 notify 和 notifyAll 來通知那些等待中的執行緒重

java執行結合執行交替列印10次abc例項wait/notify使用的徹底理解

有個朋友看點選開啟連結 裡的三個執行緒“A執行緒列印10次A,B執行緒列印10次B,C執行緒列印10次C,要求執行緒同時執行,交替列印10次ABC。” 這個問題的程式碼,有點不太理解,讓我給看下。不

五、JAVA執行執行間通訊(wait、notify、notifyAllwait set、自定義鎖 BooleanLock )

       我們在開發多執行緒程式的時候,往往不會只存在一個獨立的執行緒,相反大多數情況下是需要多個執行緒之間進行協同工作的,如何在多個執行緒之間進行通訊,是本章學習的重點。另外,本章的最後部分將會分析synchronized關鍵字的缺陷,我們手動實現了一個

執行執行之間的協作(join、wait、notify、notifyAll、await、signal、signalAll)

當多個執行緒可以一起工作去解決某個問題時,如果某些部分必須在其它部分之前完成,那麼就需要對執行緒進行協調。 join() 線上程中呼叫另一個執行緒的 join() 方法,會將當前執行緒掛起,而不是忙等待,直到目標執行緒結束。 對於以下程式碼,雖然 b 執行緒先啟動,但是因為在 b 執

【本人禿頂程式設計師】執行為什麼在while迴圈中加入System.out.println執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

執行為什麼在while迴圈中加入System.out.println執行可以停止

在論壇看到這樣一個程式碼: public class StopThread { private static boolean stopRequested; public static void main(String[] args) throws InterruptedE

Java執行/併發20、Future實現FutureTask

FutureTask是future的實現類,它同時實現了兩個介面:Runnable和Future,所以它既可以作為Runnable被執行緒執行,又可以作為Future得到Callable的返回值。 因此我們可以: - 呼叫FutureTask物件的ru

Android---執行繼承Thread 類和實現Runnable 介面的區別

參考: Java中執行緒的建立有兩種方式: 1、通過繼承Thread類,重寫Thread的run()方法,將執行緒執行的邏輯放在其中。多個執行緒分別完成自己的任務。 2、通過實現Runnable介面,例項化Thread類。多個執行緒共同完成一個任務

python中執行的共享資料通過queue來實現內有生產者消費者經典模型的示例程式碼

queue:佇列,即先進先出,它有以下幾個方法: 1.判斷佇列的大小:size() 2.向佇列中新增:put() 3.向佇列中取出:get() 4.如果佇列規定了長度,用來判斷是否滿了:full() import threading,time import queu

android 利用java中的執行和io流最快速度的下載伺服器檔案,android 實現apk下載展現通知欄

首先,我們得來說下多執行緒下載實現的大致思路,以及在使用多執行緒下載過程應該需要注意的問題。      多執行緒下載實現的大致思路:      大致思路是這樣的,也就是把整個一個檔案資源分為若干個部分,然後開啟若干個執行緒,並且使得每個執行緒負責下載每個子部分的檔案,由於

Java執行之 使用wait和notify實現生產者消費者模型

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

java實現FTP執行斷點續傳上傳下載!

package com.ftp;  import java.io.File;    import java.io.FileOutputStream;    import java.io.IOException;    import java.io.InputStream;    import java.io

Java 執行InheritableThreadLocal 實現原理

轉載自https://github.com/pzxwhc/MineKnowContainer/issues/20 前言 介紹 InheritableThreadLocal 之前,假設對 ThreadLocal 已經有了一定的理解,比如基本概念,原理,如果沒有,可以參

執行wait(),notify()和notifyall()方法的含義

在“synchronized(obj){··········}”這個同步塊中,obj物件叫做監控器,只有持有監控器這個物件的鎖時才會執行同步塊中的內容Java中的執行緒的生命週期大體可分為5種狀態。1. 新建(NEW):新建立了一個執行緒物件。2. 可執行(RUNNABLE)

java執行執行同步synchronized(不同步的問題、佇列與鎖)死鎖的產生和解決

# 0、不同步的問題 併發的執行緒不安全問題: 多個執行緒同時操作同一個物件,如果控制不好,就會產生問題,叫做執行緒不安全。 我們來看三個比較經典的案例來說明**執行緒不安全的問題**。 ## 0.1 訂票問題 例如前面說過的黃牛訂票問題,可能出現負數或相同。 [執行緒建立方式&&黃牛訂票