zoukankan      html  css  js  c++  java
  • synchronized中判断条件用while而不是if

    假设一个生产者生产一个产品,两个消费者A,B去取这个商品。

    使用if:

    A去取商品,发现空,于是等待...

    B去取商品,发现空,于是等待...

    生产者生产商品,唤醒他们

    B先争到锁,从wait()后执行代码,跳出if,取走商品。

    A后争到锁,从wait()处出发,跳出if,发现竟然没东西,取东西失败,越界。

    结果

    改用while

    A去取商品,发现空,于是等待...

    B去取商品,发现空,于是等待...

    生产者生产商品,唤醒他们

    B先争到锁,从wait()后执行代码,再次执行while,发现不必进入while,于是取走商品。

    A后争到锁,从wait()处出发,再次执行while,符合循环条件,等待。

     结果

    代码生产者

     1 package whileinsyn;
     2 
     3 import java.util.List;
     4 
     5 public class addsir implements Runnable{
     6     private List<String> list;
     7     public addsir(List<String> list) {
     8         this.list=list;
     9     }
    10     
    11     @Override
    12     public void run() {
    13         // TODO Auto-generated method stub
    14                 synchronized(list) {
    15                     System.out.println("生产者生产食品中...");
    16                     try {
    17                         Thread.sleep(1000);
    18                     } catch (InterruptedException e) {
    19                         // TODO Auto-generated catch block
    20                         e.printStackTrace();
    21                     }
    22                     list.add("食品哈哈哈");
    23                     System.out.println("已生产完毕食品哈哈哈.*&*.");
    24                     list.notifyAll();
    25                 }
    26 
    27             System.out.println("生产者今日生产量已完成...");        
    28     }
    29     
    30 }
    View Code

    代码消费者

     1 package whileinsyn;
     2 
     3 import java.util.List;
     4 
     5 public class deletesir implements Runnable{
     6     private List<String> list;
     7     public deletesir(List<String> list) {
     8         this.list=list;
     9     }
    10     @Override
    11     public void run() {
    12         // TODO Auto-generated method stub
    13             synchronized(list) {
    14                 while(list.size()==0) {
    15                     System.out.println("仓库无货,请消费者"+Thread.currentThread().getName()+"稍后再来...");
    16                     try {
    17                         list.wait();
    18                     } catch (InterruptedException e) {
    19                         // TODO Auto-generated catch block
    20                         e.printStackTrace();
    21                     }
    22                 }
    23                 System.out.println("消费者"+Thread.currentThread().getName()+"正在取走货物...");
    24                 try {
    25                     Thread.sleep(1000);
    26                 } catch (InterruptedException e) {
    27                     // TODO Auto-generated catch block
    28                     e.printStackTrace();
    29                 }
    30                 System.out.println("消费者"+Thread.currentThread().getName()+"已取走"+list.remove(0));
    31                 //list.notifyAll();
    32         }
    33     }
    34     
    35 }
    View Code

    主类

     1 package whileinsyn;
     2 
     3 import java.util.*;
     4 
     5 public class Main {
     6     public static void main(String[] args) throws InterruptedException {
     7         List<String> list=new ArrayList<>();
     8         Thread provider=new Thread(new addsir(list));
     9         Thread consumer01=new Thread(new deletesir(list),"一号");
    10         Thread consumer02=new Thread(new deletesir(list),"二号");
    11         
    12         
    13         consumer01.start();
    14         consumer02.start();
    15         Thread.sleep(3000);
    16         provider.start();
    17         
    18     }
    19 }
    View Code
  • 相关阅读:
    PHPEXCEL使用实例
    php文件上传及mime类型大全
    此时无法停用连接。这个连接可能在用一个或多个不支持即插即用的协议,或者它是由其他用户或系统帐户初始化的。
    关于LineChart线条颜色和粗细的问题
    php读取excel类——PHPExcelReader
    windowsXP激活
    主机win7 虚拟机xp 不能上网的解决方案
    linux下载文件命令wget
    PHP 合并两个PDF成一个PDF文件利器 FPDI
    php 利用ExcelReader实现EXCEL转换成缓存
  • 原文地址:https://www.cnblogs.com/heyboom/p/9147469.html
Copyright © 2011-2022 走看看