zoukankan      html  css  js  c++  java
  • 多线程为何用while判断条件,而不用if。

    一、代码:

     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

      

      

      

  • 相关阅读:
    学习Py——自己模拟写的一个Range功能
    心情随笔20180529
    记一次排查局网内的ARP包 “不存在的” MAC 地址及 “不存在的”IP 所发的ARP包
    最长反链
    浅谈矩阵树定理
    毒瘤dp 学校食堂
    P3565 由简单的树形dp 引入 长链刨分
    noi 2017 整数
    记人生的抉择
    2019 HL SC day10
  • 原文地址:https://www.cnblogs.com/shoubianxingchen/p/4922372.html
Copyright © 2011-2022 走看看