问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

java 生产者消费者 线程优先级问题

发布网友 发布时间:2022-05-01 07:48

我来回答

5个回答

热心网友 时间:2022-06-26 07:54

1、容器或者线程在生产或消费时需要先判断容器是否为空、是否已满,容器没有自定义的话,就要在线程类中每次生产之前判断容器是否已满(这个已经由容器判断),在消费时要判断容器是否为空

2、一般,线程同步最好用synchronized关键字锁定同步代码,然后通过wait()和notify()方法实现线程同步,不过容器容量大一点才能看到效果。代码如下:
class BQProc implements Runnable {
private BlockingQueue<Integer> queue;

public BQProc(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public void run() {
synchronized(queue) {
for (int proct = 1; proct <= 10; proct++) {

try {
if(queue.size() == 5) {
queue.wait();
}
queue.put(proct);// 放进去一个
System.out.println("放在 --> " + this.queue.size());
queue.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

class BQConsume implements Runnable {
private BlockingQueue<Integer> queue;

public BQConsume(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public void run() {
synchronized(queue) {
for (int i = 1; i <= 10; i++) {
try {
if(queue.isEmpty()) {
queue.wait();
}
System.out.println("拿出 <-- " + this.queue.size());
queue.take();// 拿出来一个
queue.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
放在 --> 1
放在 --> 2
放在 --> 3
放在 --> 4
放在 --> 5
拿出 <-- 5
拿出 <-- 4
拿出 <-- 3
拿出 <-- 2
拿出 <-- 1
放在 --> 1
放在 --> 2
放在 --> 3
放在 --> 4
放在 --> 5
拿出 <-- 5
拿出 <-- 4
拿出 <-- 3
拿出 <-- 2
拿出 <-- 1

PS:当基数大到一定程度才可以看到想要的结果
3、如果一定要用Thread.sleep()实现的话可以用循环控制,代码如下:

class BQProc implements Runnable {
private BlockingQueue<Integer> queue;

public BQProc(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public void run() {
for (int proct = 1; proct <= 10; proct++) {

try {
while(queue.size() == 5) {
Thread.sleep(1000);
}
Thread.sleep((int) (Math.random() * 1000));
queue.put(proct);// 放进去一个
System.out.println("放在 --> " + this.queue.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

class BQConsume implements Runnable {
private BlockingQueue<Integer> queue;

public BQConsume(BlockingQueue<Integer> queue) {
this.queue = queue;
}

public void run() {
for (int i = 1; i <= 10; i++) {
try {
while(queue.isEmpty()) {
Thread.sleep(1000);
}
Thread.sleep((int) (Math.random() * 1000));
System.out.println("拿出 <-- " + this.queue.size());
queue.take();// 拿出来一个
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
执行结果:
放在 --> 1
放在 --> 2
拿出 <-- 2
拿出 <-- 1
放在 --> 1
拿出 <-- 1
放在 --> 1
放在 --> 2
拿出 <-- 2
放在 --> 2
放在 --> 3
拿出 <-- 3
拿出 <-- 2
放在 --> 2
放在 --> 3
拿出 <-- 3
放在 --> 3
拿出 <-- 3
拿出 <-- 2
拿出 <-- 1

热心网友 时间:2022-06-26 07:54

queue.put(proct);//将指定元素添加到此队列中,如果没有可用空间,将一直等待 .
queue.take();//检索并移除此队列的头部,如果此队列不存在任何元素,则一直等待

不管你设置优先级..肯定是先执行queue.put() 因为 里面没有值.
当queue.put()抢到线程的时候一次执行5次(应该可以更多,因为你*了可用空间5个值),所以它才会停止了让给queue.take()

你可以在
System.out.println("放在 --> "+ this.queue.size());
Thread.sleep(1000);
后面加入一个停止1秒钟.就能看到效果了

热心网友 时间:2022-06-26 07:55

真正的原因是---------------------------
第一个时间永远等于0,等于是sleep(0)了,不信的话打出来看看就知道了。
就是这句话Thread.sleep((int) Math.random() * 3000);
少了一个括号发现没,应该是
Thread.sleep((int) (Math.random() * 3000));
但你的第二个没少括号,所以第一个不会sleep,第二个会,就造成这种结果了
加上括号就ok

热心网友 时间:2022-06-26 07:56

不要郁闷,这是正确的。
你需要仔细品味javadoc:api/java/util/concurrent/package-summary.html#MemoryVisibility
其实从另一个角度讲,这种使用方法不对。你只有一个线程。但实际上更多的情况下用于多次线程。多次?是的,一个线程多次执行,多个线程一次执行。

热心网友 时间:2022-06-26 07:56

try {
Thread.sleep((int) (Math.random() * 3000));
queue.put(proct);//放进去一个
System.out.println("放在 --> " + this.queue.size());
} catch (InterruptedException e) {
e.printStackTrace();
}
你看看你这段代码中的Thread.sleep((int) Math.random() * 3000);
这句出问题了,正确的是Thread.sleep((int) (Math.random() * 3000));
你(int) Math.random() * 3000这里结果一直是0,这个线程根本没停,你把那个0到1的随即值取整就是0了,0*3000就是0了,就错了。
我也犯过这样的错误。netbeans里自动取整就是这么取的。我是拿颜色结果不变色了。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
清新早春古诗词四首(一树小梅花谢矣,又是落灯天气) 睡觉的时候是不是五蕴状态?梦境是不是中蕴状态? 做梦的句子很有道理 "梦中寻梦,梦非是梦。圆中求圆,圆中有圆"怎么理解? 怎样办焊工操作证? ...看漫画...已经下载了icomic...但是找了很久都没有漫画源..._百度知... ...可是不能打开,系统说你没有打开方式,怎么样才能打开??? 2+2+2=240移动一根火柴使得等式成立? 11+7=2如何只移动一根火柴使公式成立 怎么用PS给图片加边框 PS给图片加边框操作步骤 所思、所想、感想、感悟500字作文 用java实现生产者消费者问题pv操作,不知道错哪里了。 作文那一次我真后悔500字 java 编程 生产者消费者问题,请问那个大神可以帮我解决一下?在线等。。。 关于作文离题的500字检讨书 期中考试后向父母忏悔作文500字 java实现生产者和消费者问题的几种方式 “谐波测试仪″的测试原理和型号? 莫奇里为什么研制模拟计算工具? 电脑使用触笔条件 变频器供电电机的谐波功率如何计算? 电子白板上的学科工具有什么作用? 请问你知道 三相谐波滤波器的2、4、5次谐波的计算方法吗? thussat数理探究线上怎么考 短路计算软件 鸿业软件怎么把谐波法改为冷负荷系数法 消防产品ab签哪一个是贴在产品上的? 请问用matlab进行谐波分析,用的是fft加窗插值算法。加窗的程序我会写,插值的程序怎样写???你会吗? ETAP打开时出现正在搜索ETAP KEY怎么解决 我的ADS不能进行谐波仿真,求助 苏教版五上语文习作4,要500字左右,有具体事例。是要对自己的同学表达歉意的作文。急急急急啊! 审视自己的作文 500字左右 字的第5笔? 方式的式共有几笔第二笔是什么 里有几笔第五笔是 &quot;这&quot;字有几笔第六笔是 &quot;好:共几笔啊,第一笔是什么呢 巴是几笔第笔是什么? 怎么创个网站 绿的第八笔第九笔第十笔是什么? 毛笔能第二次开笔吗? 汽车电控技术飞速发展的动力和原因有哪些? 作业的业都有几笔第三笔是什么本都有几笔第五笔是什么共有几笔第四笔是什么 汽车电控技术飞速发展的动力和原因是什么? 汽车电控技术飞速发展动力和原因有哪些? 汽车电子控制技术的基础包括哪些技术? 哪字共几笔第8笔是什么 汽车发动机电控技术的发展分几个阶段 1. 汽车电子控制技术的基础包括哪些技术? 运用在汽车上的电子控制技术有哪些