1. 程式人生 > >穩了,手寫生產者消費者模式程式碼

穩了,手寫生產者消費者模式程式碼

程式碼語言:kotlin、Java

import java.util.concurrent.locks.ReentrantLock

/**
 * kotlin
 * 測試主類
 */
fun main(args : Array<String>){
    val mLock = ReentrantLock()
    val mCondition = mLock.newCondition()
    val p = Product(mLock,mCondition)
    val c = Consumer(mLock,mCondition)

    for (i in 0..1){
        val
mThreadProduct = ThreadProduct(p) val mThreadConsumer = ThreadConsumer(c) mThreadProduct.start() mThreadConsumer.start() } }
/**
*定義產品,這是是錢,動作是賺錢和花錢
**/
public class MoneyObject {
    public static String money = "";

    public static void setMoney(String v){
        money = v;
    }

    public
static String getMoney(){ return money; } }

多個生產者和消費者執行緒。當全部執行後,生產者執行緒生產資料後,可能喚醒的同類即生產者執行緒,有可能會出現如下情況:所有生產者執行緒進入等待狀態,然後消費者執行緒消費完資料後,再次喚醒的還是消費者執行緒,直至所有消費者執行緒都進入等待狀態,此時將進入“假死”。

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
*賺錢
**/
public
class Product { private ReentrantLock mLock; private Condition mCondition; public Product(ReentrantLock mLock,Condition mCondition){ this.mLock = mLock; this.mCondition = mCondition; } public void setMoney(){ try { mLock.lock(); while (!MoneyObject.getMoney().isEmpty()){ //有錢,不生產 mCondition.await(); } MoneyObject.setMoney(System.currentTimeMillis()+"人民幣"); System.out.println("賺了:"+System.currentTimeMillis() +"人民幣"); mCondition.signalAll();//生產結束,喚醒,使用signalAll()可以防止喚醒同類執行緒造成“假死”狀態 } catch (InterruptedException e) { e.printStackTrace(); }finally { mLock.unlock(); } } }
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
*花錢
**/
public class Consumer {
    private ReentrantLock mLock;
    private Condition mCondition;

    public Consumer(ReentrantLock mLock,Condition mCondition){
        this.mLock = mLock;
        this.mCondition = mCondition;
    }

    public void getMoney(){
        try{
            mLock.lock();
            while (MoneyObject.getMoney().isEmpty()){
                //沒有錢,不消費
                mCondition.await();
            }
            System.out.println("消費的金額:"+MoneyObject.money);
            MoneyObject.setMoney("");
            mCondition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            mLock.unlock();
        }
    }
}

/**
*開啟賺錢執行緒
**/
public class ThreadProduct extends Thread{
    private Product mProduct;
    private volatile int i = 5;//控制消費次數
    public ThreadProduct(Product mProduct){
        super();
        this.mProduct = mProduct;
    }

    @Override
    public void run() {
        while (i > 0){//條件改成true就可以無限迴圈
            mProduct.setMoney();
            i--;
        }
    }
}
/**
*開啟花錢執行緒
**/
public class ThreadConsumer extends Thread{
    private Consumer mConsumer;
    private volatile int i = 5;
    public ThreadConsumer(Consumer mConsumer){
        super();
        this.mConsumer = mConsumer;
    }

    @Override
    public void run() {
        while (i > 0){
            mConsumer.getMoney();
            i--;
        }
    }
}

這裡寫圖片描述

總結:面試的過程手寫這樣的程式碼應該是比較常見的,大家相互學習