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

猜你喜欢

转载自www.cnblogs.com/heyboom/p/9147469.html
今日推荐