生產者消費者問題(附代碼)& 多線程 線程池

分析:
1.在庫存爲滿時,生產者纔可以生產,同理有庫存時消費者纔可以消費,否則就等待。
2.當消費者消費完,活着生產者生產完  應該去通知對方,並釋放對象鎖
3.對象的wait方法,wait方法的作用是釋放當前線程的所獲得的鎖,
4.notifyAll() 方法, 通知(喚醒)該對象上其他等待線程,使得其繼續執行。


主類:ThreadMain

package com.wh.blog;
public class ThreadMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//實例化庫存類,並初始化庫存爲50
      Stock stock=new Stock(50);
      
     for(int i=0;i<2;i++){
    	 //設置三個消費者的子線程,消費水平分別爲:30 ,10,40 並調用啓動線程
      new Thread(new Consumer(stock,30)).start();
      new Thread(new Consumer(stock,10)).start();
      new Thread(new Consumer(stock,40)).start();
      
      //設置三個生產者的子線程,生產量分別爲:10 ,20,30 並調用啓動線程
      new Thread(new Producer(stock,10)).start();
      new Thread(new Producer(stock,20)).start();
      new Thread(new Producer(stock,30)).start();
     }
     
	}

}

庫存類:Stock

package com.wh.blog;

public class Stock {
static int MAX=100;//最大庫存量
int current;//當前庫存
public Stock(int current){
	this.current=current;
}

public  synchronized void producer(int num){
	//測試是否需要生產
	while(num+current>MAX){
		System.out.println("超出了剩餘的庫存量,當前生產了:"+num+" 個蘋果,不能存放在倉庫!");
		try {
			wait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}//while
	current=current+num;
	System.out.println("已生產了: "+num+"個蘋果 , 當前庫存爲:"+current);
	//喚醒在此對象監視器上等待的所有線程
	notifyAll();
}

public synchronized void consumer(int num){
	//測試是否需要消費
	while(num>current){
		System.out.println("消費超出了當前的庫存量,當前消費的 "+num+"個蘋果失效");
		try {
			wait();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}//while
	current=current-num;
	System.out.println("已吃掉了: "+num+"個蘋果, 當前庫存爲:"+current);
	//喚醒在此對象監視器上等待的所有線程
	notifyAll();
}
}

生產者類:Producer

package com.wh.blog;

public class Producer implements Runnable{
Stock stock;
int num;
public Producer(Stock stock,int num){
	this.stock=stock;
	this.num=num;
}
//實現了Runaable接口,並重寫run方法
@Override
public void run() {
	// TODO Auto-generated method stub
	//生產指定數量的產品 
	stock.producer(num);
}

}

消費者類:

package com.wh.blog;

public class Consumer implements Runnable{
Stock stock;
int num;
public Consumer(Stock stock,int num){
	this.stock=stock;
	this.num=num;
}
@Override
public void run() {
	// TODO Auto-generated method stub
	//消費指定數量的產品 
	stock.consumer(num);
}
}


線程基礎知識點


package study.theard;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class MyThrard {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
//      Thread bb=new Thread(able);
//       bb.setDaemon(true);
       //daemon 所謂後臺線程是指程序運行的時候在後臺提供一種通用的服務 當所有非後臺線程結束時 才結束
//       isDaemon()方法來確認線程是否爲後臺線程
       
       
//       sleep休眠 將任務執行中止給定的時間
//       老版 的 Thread.sleep(100)
//       try {
//		TimeUnit.MILLISECONDS.sleep(100);
//	} catch (InterruptedException e) {
//		// TODO Auto-generated catch block
//		e.printStackTrace();
//	}
       
       
//     getPriority() setPriority() 在任何時候獲取和設置線程優先級  
//       bb.yield();讓步 但並不保證 會被採納
       
       
//       CachedThreadPool會將初始化的線程緩存起來 會終止從緩存中移除已有很久沒用的線程。
//       ExecutorService 具有服務生命週期的Executor 創建 關閉
          ExecutorService exec=Executors.newCachedThreadPool();
          for(int i=0;i<3;i++){
          exec.execute(able);
          }
 
          exec.shutdown();
          
//          ExecutorService execb=Executors.newFixedThreadPool(5);
          //固定的 省了創建是的開銷 
         
          
         
         
	}
	 static Runnable able=new Runnable(){

   		@Override
   		public void run() {
   			// TODO Auto-generated method stub
   			for(int i=0;i<80;i++)
   				System.out.println("k= "+i);
   		
   		}
   		
   	};
   	static Callable call=new Callable(){

		@Override
		public String call() throws Exception {
			// TODO Auto-generated method stub
			return "???";
		}
   		
   	};

}



發佈了18 篇原創文章 · 獲贊 3 · 訪問量 8755
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章