线程中用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(),没弄明白。
...全文
563 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)

62,612

社区成员

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

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