穩了,手寫生產者消費者模式程式碼
阿新 • • 發佈:2019-01-31
程式碼語言: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--;
}
}
}
總結:面試的過程手寫這樣的程式碼應該是比較常見的,大家相互學習