1. 개념
생산자와 소비자의 문제는 Jindian의 다중 스레드 협력의 문제입니다. 생산자는 제품을 생산하고 창고에 보관할 책임이 있습니다. 소비자는 창고에서 제품을 얻고 소비합니다. 창고가 가득 차면 생산자는 제품을 저장할 위치가있을 때까지 생산을 중단해야합니다. 창고가 비어 있으면 소비자는 창고에 제품이있을 때까지 소비를 중단해야합니다.
다음 기술은 주로 생산자/소비자 문제를 해결하는 데 사용됩니다. 1. 스레드를 사용하여 생산자를 시뮬레이션하고 런 방법의 창고에 제품을 지속적으로 저장하십시오. 2. 스레드를 사용하여 소비자를 시뮬레이션하고 런 방법의 창고에서 지속적으로 제품을 얻습니다. 3
. 창고 클래스는 제품을 저장합니다. 제품 수가 0 인 경우 대기 방법이 호출되어 현재 소비자 스레드가 대기 상태로 들어갑니다. 신제품이 저장되면 대기 소비자 스레드를 깨우기 위해 알림 메소드가 호출됩니다. 창고가 가득 차면 대기 방법이 호출되어 현재 생산자 스레드가 대기 상태로 들어갑니다. 소비자가 제품을 얻을 때, 대기 생산자 스레드를 깨우도록 Notify 메소드가 호출됩니다.
2. 예
PACKED BOOK.thread.Product; 공공 클래스 소비자 확장 스레드 {개인 창고 창고; // 소비자가 제품을 얻는 창고 개인 부울 런닝 = 거짓; // 최종 스레드의 플래그 비트 (창고 창고, 문자열 이름) {Super (이름); this.warehouse = 창고; } public void start () {this.running = true; super.start (); } public void run () {제품 제품; try {while (running) {// 창고 제품에서 제품을 가져옵니다 = Warehouse.getProduct (); 수면 (500); }} catch (InterruptedException e) {e.printstacktrace (); }} // 소비자 스레드 중지 공개 void stopconsumer () {synchronized (Warehouse) {this.running = false; Warehouse.NotifyAll (); // Warehouse를 기다리는 스레드}} // 소비자 스레드가 공개 Boolean isrunning () {return running; }} package book.thread.product; public class producer 확장 스레드 {개인 창고 창고; // 제조업체는 제품의 창고를 저장합니다. Private static int producename = 0; // 제품의 이름 개인 부울 실행 = false; // 최종 스레드의 플래그 비트 (창고 창고, 문자열 이름) {super (name); this.warehouse = 창고; } public void start () {this.running = true; super.start (); } public void run () {제품 제품; // 제품을 제작하고 저장하십시오. {while (running) {product = 신제품 ((++ productName)+""); this.warehouse.storageProduct (제품); 수면 (300); }} catch (InterruptedException e) {e.printstacktrace (); }} // 생산자 스레드 중지 공개 void stopproducer () {synchronized (Warehouse) {this.running = false; // 창고 창고 창고 창고를 기다리는 스레드에 알림. }} // 생산자 스레드가 실행 중인지 공개 부울 isrunning () {return running; }} package book.thread.product; 공개 클래스 제품 {개인 문자열 이름; // 제품 이름 공개 제품 (문자열 이름) {this.name = name; } public String toString () {return "roduct-"+name; }} package book.thread.product; // 제품의 창고 클래스는 배열을 사용하여 원형 큐를 사용하여 제품 공개 클래스 창고 {private static int capacity = 11; // Warehouse Private Product의 용량 [] 제품의 제품; 0; // 창고에서 마지막으로 전달되지 않은 제품의 첨자와 1 public Warehouse () {this.products = 신제품 [용량]; } 공공 창고 (int 용량) {this (); if (용량> 0) {용량 = 용량 +1; this.products = 신제품 [용량]; }} // 창고에서 제품 가져 오기 getProduct () getProduct ()는 InterpruptedException {synchronized (this) {boolean consiperrunning = true; // 소비자 스레드가 여전히 실행 중인지에 대한 태그 currentthread = thread.currentThread (); // 소비자의 현재 스레드를 얻는다 (소비자)). } else {return null; // 소비자가 제품을 얻을 수 있습니다} // 소비자 스레드가 실행중인 경우 창고에 제품이 없으면 소비자 스레드는 계속 기다립니다 ((Front == rear) && consumErrunning) {Wait (); ConsecerRunning = ((소비자) currentthread) .isrunning (); } // 소비자 스레드가 실행을 중지 한 경우 메소드를 종료하고 제품을 취소합니다. } // 현재에서 소비되지 않은 첫 번째 제품을 얻습니다. 제품 제품 = 제품 [Front]; System.out.println ( "소비자 ["+currentthread.getName ()+"] getProduct :"+upbuture); // 현재 무의미한 제품의 위시를 하나씩 옮기십시오. 배열 끝에 도달하면 헤더 전면으로 이동합니다 = (전면+1+용량)%용량; System.out.println ( "창고에 아직 소비되지 않은 제품의 수량 :"+(후면+용량 전기)%용량); // 다른 대기 스레드 알림 notify (); 반품 제품; }} // 제품을 창고에 저장 공개 공공 void StorageProduct (Product Product)는 InterruptedException {synchronized (this) {boolean producerRunning = true; // 제작자 스레드가 실행 중인지 여부에 관계없이 currentthread = stread.currentthread (); if (currentthread 인스턴스) {producerRunning = ((Producer) currentthread) .isrunning (); } else {return; } // 마지막으로 전달되지 않은 제품이 첫 번째로 소비되지 않은 제품의 첨자 옆에있는 경우 저장 공간이 없음을 의미합니다. // 저장 공간이없고 생산자 스레드가 여전히 실행중인 경우 생산자 스레드는 창고가 제품을 해제 할 때까지 기다립니다 (((후면+1)%) 용량 == FRONT) && producerRunning) {Wait (); ProduceRrunning = ((Producer) Currentthread) .isrunning (); } // 프로덕션 스레드가 실행 중지 된 경우 (! ProducerRunning) {return; } // 제품을 창고 제품에 저장 [후면] = 제품; System.out.println ( "producer [" + thread.currentThread (). getName () + "] StorageProduct :" + product); // 후면 위시를 차례로 변경합니다. 후면 = (후면 + 1)%용량; System.out.println ( "창고에서 소비되지 않은 제품의 수량 :" + (후면 + 용량 -front)%); notify (); }}} package book.thread.product; public class testProduct {public static void main (String [] args) {창고 창고 = 새로운 창고 (10); 10 // 생산자 스레드 및 소비자 생산자 생산자 생산자 생산자 1 = 새로운 생산 업체 (창고 1); Producer Producers2 = New Producer (Warehouse, "Producer-2"); 프로듀서 프로듀서 3 = 새로운 생산자 (창고, "프로듀서 -3"); 소비자 소비자 1 = 새로운 소비자 (창고, "소비자 -1"); Consumer Consumer2 = 새로운 소비자 (창고, "소비자 -2"); 소비자 소비자 3 = 새로운 소비자 (창고, "소비자 -3"); 소비자 소비자 4 = 새로운 소비자 (창고, "소비자 -4"); // 생산자 스레드를 시작하고 소비자 스레드는 1.start ()를 생산합니다. Producers2.start (); 소비자 1.start (); 생산자3.start (); 소비자 2.Start (); 소비자3.Start (); 소비자 4.start (); // 1600ms의 생산자/소비자 프로그램을 실행하게하십시오 {thread.sleep (1600); } catch (InterruptedException e) {e.printstacktrace (); } // 소비자 스레드가 생성 1.stopProducer (); Consumer1.stopConsumer (); Producers2.stopProducer (); 소비자 2.StopConsumer (); Producers3.StopProducer (); 소비자3.StopConsumer (); 소비자 4.StopConsumer (); }}출력 결과 :
Producter [Producter-1] StorageProduct : 제품 1 창고에서 소비되지 않은 제품의 수 : 1 소비자 [소비자 -2] GetProduct : 제품 1 창고에서 소비되지 않은 제품의 수 : 0Producer [Producter-3] StorageProd. Product-2 창고 : 2Consumer [Consumer-3] GetProduct : Product-3 창고에서 소비되지 않은 제품의 수 : 1Consumer [Consumer-1] GetProduct : 제품 2 창고에서 소비되지 않은 제품의 수 : 0 프로듀서 [Producter-1] 제품의 수 : 제품의 수 : 4 GetProduct : Product-4 창고에서 소비되지 않은 제품의 수 : 0Producer [Producter-3] StorageProduct : Product-6 창고에서 소비되지 않은 제품의 수 : 1 프로듀서 [Producter-2] StorageProduct : Product-5 창고에서 소비되지 않은 제품의 수 : 2Consumer-1] 창고 : 1Consumer [Consumer-2] GetProduct : Product-5 창고에서 소비되지 않은 제품의 수 : 0Producer [Productrt-1] StorageProduct : 제품 -7 창고에서 소비되지 않은 제품의 수 : 1consumer [Consumer-3] GetProduct : 제품에 소비되지 않은 제품의 수 : 0. 제품 -8 창고에서 소비되지 않은 제품의 수 : 1 프로듀서 [Producer-2] StorageProduct : 제품 -9 창고에서 소비되지 않은 제품 수 : 2 소비자 [소비자 -4] GetProduct : 창고에서 소비되지 않은 제품 -1 제품 : 1 프로듀서 [Producttrostroct : 1 Producter : 1 Producter : 1 Producter : 1 Products : 2Produer [Productr-3] StorageProduct : 제품 -11 창고에서 소비되지 않은 제품 -11 제품 수 : 3 제품 제작자 [Productrt-2] StorageProduct : 창고에서 소비되지 않은 제품 -12 제품 수 : 4Consumer [소비자 -1] GetProduct : 창고에서 소비되지 않은 제품 -2. 창고에서 소비되지 않았다 : 2 소비자 [Consumer-3] GetProduct : 제품 -11 창고에서 소비되지 않은 제품 11 개 제품 : 1Producer [Productr-3] StorageProduct : 제품 13 창고에 소비되지 않은 제품 1] 2Producer [Productr-1] 창고에서 소비되지 않은 제품의 수의 수 : 3precer의 제품 수는 3precer. StorageProduct : 제품 -15 창고에서 소비되지 않은 제품 -15 제품 수 : 4 소비자 [Consumer-4] GetProduct : 제품 -12 창고에서 소비되지 않은 제품 수 : 3 소비자 [Consumer-1] GetProduct :웨어 하우스에서 소비되지 않은 제품 13 제품 : 2Consumer [Consumer-2] 제품이 없었습니다. 창고 : 1 프로듀서 [Productr-1] 스토리지 제품 : 제품 -16 창고에서 소비되지 않은 제품 1 제품 수 : 2 프로듀서 [Producer-3] StorageProduct : 제품 17 창고에서 소비되지 않은 제품 : 3Producer [Productr-2] 제품에서 소비되지 않은 제품 수 : 4
분석 : 제품 창고는 주요 방법으로 설정되어 있으며 창고는 3 개의 생산자 스레드와 4 개의 소비자 스레드를 연관시키지 않습니다. 이 스레드는 생산자/소비자 모델을 작동시키기 시작했습니다. 이 프로그램이 1600ms에 실행되면 모든 생산 업체는 제품 생산을 중단하고 소비자는 제품 소비를 중단합니다.
생산자 스레드 제품은 런 방법에 300ms없이 제품을 생산하여 창고에 저장합니다. 소비자 스레드 소비자는 런 방법에 500ms없이 창고에서 제품을 가져옵니다.
창고는 제품 저장 및 배포를 담당합니다. StorageProduct 방법은 제품 저장을 담당합니다. 창고가 가득 차면 현재 스레드가 대기 상태로 들어갑니다. 스토리지 제품이 성공하면 대기 소비자 스레드를 깨우도록 Notify 메소드가 호출됩니다.
GetProduct 방법은 사전에 제품을 담당합니다. 창고가 비어 있으면 현재 실이 대기 상태로 들어갑니다. 즉, 소비자 스레드 B가 제품을 얻기 위해 getProduct 방법을 호출하면 창고가 비어 있음을 발견하면 대기 상태로 들어갑니다. 제품이 성공적으로 추출되면 알림 방법이 호출되어 대기 생산자 스레드를 깨우십시오.
위의 기사에서는 Java 스레드에서 생산자와 소비자의 문제가 내가 공유하는 모든 콘텐츠입니다. 나는 그것이 당신에게 참조를 줄 수 있기를 바랍니다. 그리고 당신이 wulin.com을 더 지원할 수 있기를 바랍니다.