• 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
  • 相关阅读:
    lua敏感词过滤
    解决灰色shader与mask冲突的方案
    Lua加密
    不同版本Lua介绍
    如何用pycharm 控制远程服务器来跑代码!!!!!!!!!!!!非常牛逼
    如何用win10自带linux系统学习c语言---解决gdb使用问题
    分享一些机器学习,数学和工科书籍和看过的一些论文笔记都在里面
    登录网站的autohotkey脚本
    wmware虚拟化的启动问题
    茶杯头开枪ahk代码
  • 原文地址:https://www.cnblogs.com/heyboom/p/9147469.html
Copyright © 2020-2023  润新知