双11狂欢大促

盲盒赢 定制羽绒服

开启惊喜盲盒,抽取你的专属好礼

— 惊喜奖品抢先看 —

生产者&消费者咋出现死锁,牛人知道吗?

jjxiaoxuan jjxiaoxuan 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
*
* @author Administrator 生产者消费者实例
*/
public class ProducerAndCustomer {
private static Buffer buffer = new Buffer(); // 内部类,用于缓冲生产的商品数

public static void main(String args[]) {
ExecutorService executor = Executors.newFixedThreadPool(2);

executor.execute(new buyTask());
//executor.execute(new buyTask());
executor.execute(new produceTask());
//executor.execute(new produceTask());
executor.shutdown();

// System.out.println( (int)((Math.random() * 10) + 1));
}

// 执行消费者的任务
private static class buyTask implements Runnable {

@Override
public void run() {
while (true) {
buffer.buy((int) ((Math.random() * 10) + 1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

// 执行生产者的任务
private static class produceTask implements Runnable {

@Override
public void run() {
while (true) {
buffer.produce((int) ((Math.random() * 10) + 1));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

// 内部类,用于缓冲生产的商品数
public static class Buffer {
int maxNumber = 20; // 缓冲区的最大容量
private static int proNumber = 0; // 当前缓冲区的容量,为了方便,直接用整数表示
private static Lock lock = new ReentrantLock();
private static Condition notFull = lock.newCondition();
private static Condition notEmpty = lock.newCondition();

public void produce(int amount) { // 生产者的方法
lock.lock();
try {

while (proNumber == maxNumber || proNumber + amount >= maxNumber) {
System.out.println("wait for the not full condition");
notFull.await(); // 调试时这句使线程等待的语句不起作用
}
proNumber += amount;
System.out.println("produce amount :" + amount + " for the proNumber:" + proNumber);
notEmpty.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void buy(int amount) // 消费者的方法
{
lock.lock();
try {

while (proNumber == 0 || proNumber - amount <= 0) {
System.out.println("wait for the not Empty condition");
notEmpty.await();
}
proNumber -= amount;
System.out.println("buy for the amount:" + amount + "and the proNumber " + proNumber);
notFull.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}

}


console:
buy for the amount:7and the proNumber 5
produce amount :2 for the proNumber:7
buy for the amount:6and the proNumber 1
wait for the not Empty condition
produce amount :3 for the proNumber:4
wait for the not Empty condition
produce amount :4 for the proNumber:8
wait for the not Empty condition
produce amount :6 for the proNumber:14
buy for the amount:9and the proNumber 5
buy for the amount:2and the proNumber 3
produce amount :2 for the proNumber:5
buy for the amount:4and the proNumber 1
produce amount :9 for the proNumber:10
buy for the amount:7and the proNumber 3
produce amount :4 for the proNumber:7
buy for the amount:1and the proNumber 6
produce amount :10 for the proNumber:16
wait for the not full condition
buy for the amount:6and the proNumber 10
wait for the not full condition
wait for the not Empty condition

...全文

相关推荐

c#多线程之生产者消费者

c#多线程之生产者消费者

今晚打老斧QAQ

生产者消费者问题算法的实现

《生产者与消费者问题算法实现》 设计思想 因为有多个缓冲区,所以生产者线程没有必要在生成新的数据之前等待最后一个数据被消费者线程处理完毕。同样,消费者线程并不一定每次只能处理一个数据。在多缓冲区机制下,线程之间不必互相等待形成死锁,因而提高了效率。   多个缓冲区就好像使用一条传送带替代托架,传送带上一次可以放多个产品。生产者在缓冲区尾加入数据,而消费者则在缓冲区头读取数据。当缓冲区满的时候,缓冲区就上锁并等待消费者线程读取数据;每一个生产或消费动作使得传送带向前移动一个单位,因而,消费者线程读取数据的顺序和数据产生顺序是相同的。 可以引入一个count计数器来表示已经被使用的缓冲区数量。用hNotEmptyEvent 和hNotFullEvent 来同步生产者和消费者线程。每当生产者线程发现缓冲区满( count=BufferSize ),它就等待hNotEmptyEvent 事件。同样,当消费者线程发现缓冲区空,它就开始等待hNotEmptyEvent。生产者线程写入一个新的数据之后,就立刻发出hNotEmptyEvent 来唤醒正在等待的消费者线程;消费者线程在读取一个数据之后,就发出hNotFullEvent 来唤醒正在等待的生产者线程。 程序的设计思想大致为:设置一while循环,pi生产者访问临界区,得到权限访问缓冲区,如果缓冲区满的,则等待,直到缓冲区非满;访问互斥锁,当得到互斥锁且缓冲区非满时,跳出while循环,开始产生新数据,并把数据存放于Buffer缓冲区中,当数据存放结束则结束临界区;接着唤醒消费者线程;ci消费者访问临界区,得到权限访问缓冲区,如果缓冲区为空,没有可以处理的数据,则释放互斥锁且等待,直到缓冲区非空;当等到缓冲区非空时,跳出while循环;消费者获得数据,并根据所获得的数据按类别消费(当消费者获得的数据为大写字母时,则把大写字母转换成小写字母,并显示;当消费者获得的数据为小写字母时,则把小写字母转换成大写字母,并显示;当消费者获得的数据为字符0、1、2、……8、9时,把这些字符直接显示到屏幕;当消费者获得的数据为符号(+、-、*、\……)时,把这些符号打印成7行7列的菱形);处理完数据后,结束临界区;接着唤醒生产者线程。

kylin_bb

Java——生产者-消费者问题

本程序模拟实现了“生产者-消费者”问题的解决过程,用图形界面动态演示了P、V操作过程以及生产者、消费者进程之间的工作流程。 本程序使用的算法是典型的P、V操作使用信号量解决“生产者-消费者”问题。 本程序在界面上使用了Java的swing接口函数,用矩形条表示生产者进程中待生产的产品,并设置了三个分区分别表示生产者进程待生产的产品、公共缓冲池中已生产的产品和消费者进程已消费的产品,以动画的效果动态演示了待生产产品变成消费者进程中已消费产品的过程,以及在这一过程中生产者进程和消费者进程协调工作的过程。 在程序运行过程中使用了两个生产者线程和两个消费者线程并发工作,并使用了线程随机休眠的策略,

weixin_38522529

解决线程死锁问题的 生产者 消费者程序.rar_linux_linux 线程_生产者_生产者 消费者_生产者消费者

解决线程死锁问题的 生产者 消费者程序

刘良运

生产者与消费者pv原语

操作系统作业,生产者与消费者,编程软件vc++

wybwjl
评论 1
收藏 已收藏
分享
返回顶部
jjxiaoxuan
Java 51,407 成员 86,134 内容