代码语言: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--;
}
}
}
总结:面试的过程手写这样的代码应该是比较常见的,大家相互学习