码迷,mamicode.com
首页 > 编程语言 > 详细

多线程为何用while判断条件,而不用if。

时间:2015-10-30 10:47:30      阅读:447      评论:0      收藏:0      [点我收藏+]

标签:

一、代码:

技术分享
 1 package zz.produceandconsumer;
 2 
 3 import java.util.LinkedList;
 4 
 5 public class Storage {
 6     
 7     private final static int MAX_NUM=100;
 8     
 9     private volatile LinkedList<Object> list=new LinkedList<Object>();
10     
11     public void produce(int pNum){
12         synchronized(list){
13             if(list.size()+pNum>MAX_NUM){
14                 System.out.println("当前商品数量:"+list.size()+",欲生产数量:"+pNum+",超过最大容量:"+MAX_NUM+".");
15                 try {
16                     list.wait();
17                 } catch (InterruptedException e) {
18                     e.printStackTrace();
19                 }
20             }
21 //            while(list.size()+pNum>MAX_NUM){
22 //                System.out.println("当前商品数量:"+list.size()+",欲生产数量:"+pNum+",超过最大容量"+MAX_NUM+".");
23 //                try {
24 //                    list.wait();
25 //                } catch (InterruptedException e) {
26 //                    e.printStackTrace();
27 //                }
28 //            }
29             int i=0;
30             while(i<pNum){
31                 System.out.println("欲生产:"+pNum+",list.size:"+list.size()+",最大值:"+MAX_NUM+",i:"+i);
32                 list.add(new Object());
33                 i++;
34             }
35             System.out.println("生产了"+pNum+"个商品,仓库中存货"+list.size()+".");
36             list.notifyAll();
37         }
38     }
39     
40     public void consumer(int cNum){
41         synchronized(list){
42 //            if(cNum>list.size()){
43 //                System.out.println("当前商品数量:"+list.size()+",欲消费数量:"+cNum+",数量不足.");
44 //                try {
45 //                    list.wait();
46 //                } catch (InterruptedException e) {
47 //                    e.printStackTrace();
48 //                }
49 //            }
50             while(cNum>list.size()){
51                 System.out.println("当前商品数量:"+list.size()+",欲消费数量:"+cNum+",数量不足.");
52                 try {
53                     list.wait();
54                 } catch (InterruptedException e) {
55                     e.printStackTrace();
56                 }
57             }
58             int i=0;
59             if(cNum>list.size()){
60                 System.out.println("error");
61             }
62             while(i<cNum){
63 //                System.out.println("size:"+list.size()+",i:"+i+",cNum:"+cNum);
64                 list.remove();
65                 i++;
66             }
67             System.out.println("消费了"+cNum+"个商品,仓库中存货"+list.size()+".");
68             list.notifyAll();
69         }
70     }
71 
72 }
View Code
技术分享
 1 package zz.produceandconsumer;
 2 
 3 public class Producer implements Runnable{
 4     
 5     private Storage storage;
 6     private int num;
 7     
 8     Producer(Storage storage,int num){
 9         this.storage=storage;
10         this.num=num;
11     }    
12     
13     public void produce(){
14         this.storage.produce(num);
15     }
16     
17     
18     @Override
19     public void run() {
20         produce();
21     }
22 }
View Code
技术分享View Code
技术分享
 1 package zz.produceandconsumer;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Storage storage=new Storage();        
 6         
 7         new Thread(new Producer(storage, 22)).start();
 8         new Thread(new Producer(storage, 11)).start();
 9         new Thread(new Consumer(storage,33)).start();
10         
11         new Thread(new Consumer(storage, 40)).start();        
12         new Thread(new Consumer(storage, 50)).start();
13         new Thread(new Producer(storage, 90)).start();
14         
15         new Thread(new Producer(storage, 65)).start();
16     }
17 
18 }
View Code

 

二、运行结果:

  2.1多次运行,可以看到结果:   

欲生产:90,list.size:151,最大值:100,i:86
欲生产:90,list.size:152,最大值:100,i:87
欲生产:90,list.size:153,最大值:100,i:88
欲生产:90,list.size:154,最大值:100,i:89
生产了90个商品,仓库中存货155.
消费了40个商品,仓库中存货115.
消费了50个商品,仓库中存货65.

    list.size大于了我们规定的最大值100.

  2.2 注释Storage中的31行代码,放开63行的代码,并打开consumer中的if,关掉while;注释掉Main中15行代码,多次运行结果:

    

size:11,i:29,cNum:33
size:10,i:30,cNum:33Exception in thread "Thread-3" java.util.NoSuchElementException
at java.util.LinkedList.removeFirst(LinkedList.java:268)
at java.util.LinkedList.remove(LinkedList.java:683)
at zz.produceandconsumer.Storage.consumer(Storage.java:64)
at zz.produceandconsumer.Consumer.consume(Consumer.java:19)
at zz.produceandconsumer.Consumer.run(Consumer.java:24)
at java.lang.Thread.run(Thread.java:745)

size:9,i:31,cNum:33
size:8,i:32,cNum:33
消费了33个商品,仓库中存货7.

 

三、分析和结论:

  用if判断,当下一个时间片轮转到该线程时,该线程的记录点可能已经在if条件判断之后了,故此该次执行会从if语句后开始执行。

故此会造成数组超过最大长度和删除空元素的错误。

  参考资料:http://www.oschina.net/question/1245392_163830

  

 

  

  

多线程为何用while判断条件,而不用if。

标签:

原文地址:http://www.cnblogs.com/shoubianxingchen/p/4922372.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!