稳了,手写生产者消费者模式代码

本文介绍了一个基于Kotlin和Java实现的生产者消费者模式案例。通过使用ReentrantLock和Condition来同步多个生产者线程和消费者线程之间的操作,避免了线程间的假死状态。文章详细展示了代码结构和关键逻辑。

代码语言: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--;
        }
    }
}

这里写图片描述

总结:面试的过程手写这样的代码应该是比较常见的,大家相互学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值