线程中用while循环

yaojianquansb 2010-07-27 03:47:04

import java.util.LinkedList;
public class Syn{
private LinkedList<Object> myList =new LinkedList<Object>();
private int MAX = 10;
public Syn(){}
public void start(){
new Producer().start();
new Consumer().start();
}
public static void main(String[] args){
Syn s1 = new Syn();
s1.start();
}
class Producer extends Thread{
public void run(){
for(int i=0;i<50;i++){
try{
sleep(10);
}catch(Exception e){
e.getMessage();
}
synchronized(myList){
try{
while(myList.size() == MAX){ //用while循环,不用if()
System.out.println("warning: it's full!");
myList.wait();
}
Object o = new Object();
if(myList.add(o)){
System.out.println("Producer: " + o);
myList.notify();
}
}catch(InterruptedException e){
System.out.println("producer is interrupted!");
}
}
}
}
}
class Consumer extends Thread{
public void run(){
for(int i=0;i<50;i++){
try{
sleep(100);
}catch(Exception e){
e.getMessage();
}
synchronized(myList){
try{
while(myList.size() == 0){ ////用while循环,不用if()
System.out.println("warning: it's empty!");
myList.wait();
}
Object o = myList.removeLast();
System.out.println("Consumer: " + o);
myList.notify();
}catch(InterruptedException ie){
System.out.println("consumer is interrupted!");
}
}
}
}
}
}
//rt,多线程的生产者消费者模式,一个生产者和一个消费者,帮解释下为何不用if,要用while(),没弄明白。
...全文
619 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
jays1235 2010-07-31
  • 打赏
  • 举报
回复
while可以防止if那样不检查条件继续向下执行代码了
怪人伽利略 2010-07-31
  • 打赏
  • 举报
回复
第一个用if是为了保证生产者已经生产成功,第二个就不用了,建议找一下操作系统里面有很详细的解答!
avalon 2010-07-31
  • 打赏
  • 举报
回复
线程一般多用while(){},因为多线程具有不确定性,用if(){}可能在条件未完全满足的情况继续往下执行了,造成了错误。
littleJP 2010-07-29
  • 打赏
  • 举报
回复
刚刚学多线程 还没怎么明白 学习学习……
pywepe 2010-07-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 chooseforget 的回复:]

Java code

while(myList.size() == 0){ ////用while循环,不用if()
System.out.println("warning: it's empty!");
myList.wait();
……
[/Quote]

当然有区别 if只有一次 while可以不止一次
myList.wait();这里wait后,线程等在这里
等到别个线程nofity后
继续执行,这时是有必要再判断myList.size()的大小的
简单地,满了的水桶不能再装水进去了
zhuzeitou 2010-07-28
  • 打赏
  • 举报
回复
wait()即为wait(0),并不是一直等到Producer/Consumer执行完才唤醒,而是wait一个很短的固定的时间就被唤醒,你不能保证在这段时间内Producer/Consumer已经执行完
Java_etoak_keke 2010-07-28
  • 打赏
  • 举报
回复
这里用while而不用if是因为while可以当myList.size() == MAX为真的时候实现无限循环,这样子既能是这个线程进入等待队列又能释放自己的锁标记,从而使consumer线程执行;
第二个使用while也是等到linckenlist为空的时候无限循环打印"warning: it's empty!而if不能实现循环。
yaojianquansb 2010-07-28
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yktd26 的回复:]
第一个可跳出循环,
第二个永远跳不出
[/Quote]
wait中断后就跳出了啊?
yktd26 2010-07-28
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yaojianquansb 的回复:]
引用 8 楼 yktd26 的回复:
第一个可跳出循环,
第二个永远跳不出

wait中断后就跳出了啊?
[/Quote]
我这说的五楼的
yktd26 2010-07-27
  • 打赏
  • 举报
回复
不过之前没看到你下面一行写一个生产者一个消费者,如果是这样,用if应该也没有太大问题,如果没有其他线程加同一个锁的话
不过用while更符合逻辑,才是纯粹的线程安全
yaojianquansb 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 yktd26 的回复:]

引用 14 楼 yaojianquansb 的回复:
引用 4 楼 yktd26 的回复:
因为多线程
多用户
比如说,某个用户第一次得到锁时list为空,他wait,下次被唤醒时,list可能还是空的。因为有肯能其他用户购买了产……
[/Quote]
如果是一个生产者和一个用户呢?
yktd26 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 yaojianquansb 的回复:]
引用 4 楼 yktd26 的回复:
无法保证一次wait后list中就不满了或不空了,所以while

为什么不能保证一次wait后list中就不满了或不空了?帮忙解释下,谢谢啊。。。
[/Quote]
因为多线程
多用户
比如说,某个用户第一次得到锁时list为空,他wait,下次被唤醒时,list可能还是空的。因为有肯能其他用户购买了产品清空了表。如果用if他将不再判断list是否为空,直接继续,引起错误
但如果用while则每次被唤醒时都先检查list是否为空再继续

生产基本是一个道理
yaojianquansb 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yktd26 的回复:]
无法保证一次wait后list中就不满了或不空了,所以while
[/Quote]
为什么不能保证一次wait后list中就不满了或不空了?帮忙解释下,谢谢啊。。。
yaojianquansb 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhuzeitou 的回复:]
你无法保证你的一次wait()过后Consumer/Producer操作已经完成
举个例子:如果你在Consumer中遇到货物为空,需要wait,如果你wait结束后Producer的生产操作仍然没有完成,而你又用了if,那么你就将在货物为空的情况下执行消费动作,显然这是有问题的。而用while的话则保证在货物为空时不会跳出循环,避免了这个问题
[/Quote]
没有完全理解啊,Producer的生产操作没有完成的话,怎么在货物为空的情况下执行消费动作啊?不是要等Producer的生产操作完成,唤醒Consumer并退出同步块,释放对象锁之后才有可能继续消费吗?为什么不能保证?悟性太低,sorry啊...
lost_guy_in_scut 2010-07-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zhuzeitou 的回复:]
你无法保证你的一次wait()过后Consumer/Producer操作已经完成

举个例子:如果你在Consumer中遇到货物为空,需要wait,如果你wait结束后Producer的生产操作仍然没有完成,而你又用了if,那么你就将在货物为空的情况下执行消费动作,显然这是有问题的。而用while的话则保证在货物为空时不会跳出循环,避免了这个问题
[/Quote]
正解。
tnt532185987 2010-07-27
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
因为刚被唤醒后,有可能又被其他线程塞满,所以需要再次判断。
tnt532185987 2010-07-27
  • 打赏
  • 举报
回复
试一下 回复功能
yktd26 2010-07-27
  • 打赏
  • 举报
回复
第一个可跳出循环,
第二个永远跳不出
tnt532185987 2010-07-27
  • 打赏
  • 举报
回复
加载更多回复(6)
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,通过Matlab代码实现了控制算法的仿真验证。该方法融合强化学习的在线自适应能力与传统PID控制的稳定性优势,利用QLearning算法动态优化PID控制器的比例、积分、微分参数,以应对水下复杂流体环境、模型不确定性及外部干扰等挑战,从而提升AUV轨迹跟踪的精度、鲁棒性与动态响应性能。文中系统阐述了AUV的六自由度非线性动力学建模过程、QLearning算法的状态空间与动作空间设计、奖励函数构造及训练机制,并详细说明了PID参数自整定的闭环控制架构。仿真结果表明,相较于传统固定参数PID控制器,该智能控制策略在多种工况下均展现出更优的控制效果,有效抑制了超调,加快了响应速度,并增强了抗干扰能力。; 适合人群:具备自动控制理论、强化学习基础及Matlab/Simulink仿真能力,从事水下机器人、智能控制、海洋工程、自动化等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于AUV、UUV等无人水下平台的高精度自主导航与运动控制;②为解决非线性、强耦合、时变系统的控制器参数自适应整定问题提供智能化解决方案;③作为强化学习与经典控制理论深度融合的技术范例,推动智能控制算法在海洋装备中的工程化应用。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点剖析QLearning的状态-动作-奖励机制设计、PID参数更新逻辑及仿真对比实验结果,有条件者可在更复杂的动力学模型或实际硬件平台上进一步验证与优化算法性能。

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧