java多線程生產者/消費者示例代碼

多線程管理

  • 線程類
    –通過繼承Thread或實現Runable
    – 通過start方法,調用run方法,run方法工作
    – 線程run結束後,線程退出
  • 粗粒度: 子線程與子線程之間、和main線程之間缺乏同步
  • 細粒度:線程之間有同步協作
    – 等待
    – 通知/喚醒
    – 終止
    • 等待:等A線程執行到某一個地方的時候,B線程告A線程,讓A等待一會,等A到了,在往下一起走
    • 通知/喚醒: A到了,A告訴B,我到了,可以走了
    • 線程狀態
      – NEW 剛創建(new)
      – RUNNABLE 就緒態(start)
      – RUNNING 運行中(run)
      – BLOCK 阻塞(sleep)
      – TERMINATED 結束
      在這裏插入圖片描述
  • Thread的部分API已經廢棄
    – 暫停和恢復spspend/resume (這些方法很危險,已經廢棄,不建議使用)
    – 消亡 stop/destroy (這些方法很危險,已經廢棄,不建議使用)
  • 線程阻塞/和喚醒
    – sleep,時間一到,自己會醒來
    – wait/notify/notifyAll 等待,需要別人來喚醒
    – join 等待另外一個線程結束
    – interrupt 向另外一個線程發送中斷信號,該線程收到信號,會觸發InterruptedException(可解除阻塞),並進行下一步處理
    • wait: 休眠狀態,等別的線程調用notify或者notifyAll的時候,可以醒來。一個等待(wait)的線程是需要其他線程去喚醒的,如果沒有其他線程去喚醒它,那這個線程就一直等待,一直處於休眠狀態

生產者/消費者示例:

經典生成者與消費者問題
生產者不斷的往倉庫中存放產品,消費者從倉庫中消費產品。
其中生產者和消費者都可以有若干個。
倉庫規則:容量有限,庫滿時不能存放,庫空時不能取產品。

源碼示例:

//產品
public class Product  {
    private Integer id;
    private String name;
    }
package product;

/**
 * @ClassName:Storage
 * @Description:倉庫類
 * @author: Torey
 */
public class Storage {
    //倉庫容量
    public Storage(Integer volume) {
        this.products = new Product[volume];
        this.volume=volume;
    }
    //倉庫容量
    private Integer volume;

    public Integer getVolume() {
        return volume;
    }

    public void setVolume(Integer volume) {
        this.volume = volume;
    }

    //倉庫容量
    private Product[] products ;

    private int top = 0;
//生產者向倉庫中放入產品
    public synchronized void push(Product product){
        while (top == products.length) {
            try {
                System.out.println("product wait");
                wait();//倉庫已滿,等待
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        //把產品放入倉庫
        products[top++]=product;
        System.out.println("producer notifyAll"+Thread.currentThread().getName() + "生產了產品:"+product);
        notifyAll();//喚醒等待線程
    }
    //消費者從倉庫中取出產品
    public synchronized Product pop() {
        while (top == 0) {
            try{
            System.out.println("empty! consumer wait");
            wait();}catch (Exception ex){
                ex.printStackTrace();
            }
        }
        //從倉庫中取產品
        --top;
        Product p = new Product(products[top].getId(), products[top].getName());
        products[top]=null;
        System.out.println("comsumer notifyAll "+Thread.currentThread().getName() + " 消費了產品:" + p);
        notifyAll(); //喚醒等待的線程
        return p;
    }
}

package product;
/**
 * @ClassName:Consumer
 * @Description:消費者
 * @author: Torey
 */
public class Consumer implements Runnable {
    private Storage storage;

    /**
     *
     * @param storage 倉庫
     * @param interval 多久消費一個
     */
    public Consumer(Storage storage,Integer interval) {
        this.storage = storage;
        this.integer=interval*1000;
    }
private Integer integer;
    @Override
    public void run() {
        int i=0;
        while (true){
            try {
                i++;
               storage.pop();
                Thread.sleep(integer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
package product;
import java.util.Random;

/**
 * @ClassName:Producer
 * @Description:生產者
 * @author: Torey
 */
public class Producer implements Runnable {
    private Storage storage;

    /**
     *
     * @param storage 倉庫
     * @param integer 多久生產一個
     */
    public Producer(Storage storage,Integer integer) {
        this.storage = storage;
        this.integer=integer*1000;
    }
    private Integer integer;
    @Override
    public void run() {
        int i=0;
        Random r = new Random();
        while (true){
            i++;
            Product product = new Product(i, "電話" + r.nextInt(100));
            try {
                Thread.sleep(integer);
                storage.push(product);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
package product;
/**
 * @ClassName:ProductTest
 * @Description:
 * 經典生成者與消費者問題
 * 生產者不斷的往倉庫中存放產品,消費者從倉庫中消費產品。
 * 其中生產者和消費者都可以有若干個。
 * 倉庫規則:容量有限,庫滿時不能存放,庫空時不能取產品。
 * @author: Torey
 */
public class ProductTest {
    public static void main(String[] args) throws InterruptedException {
        //倉庫容量爲 5個
        Storage storage = new Storage(5);
        //每5秒鐘消費一次
      new Thread(new Consumer(storage,5),"消費者1").start();
  //每秒生產一個
       new Thread(new Producer(storage,1),"生產者2").start();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章