码迷,mamicode.com
首页 > 其他好文 > 详细

Study for Test

时间:2019-12-04 01:26:48      阅读:101      评论:0      收藏:0      [点我收藏+]

标签:生产线   ide   private   getname   current   tac   name   消费   trace   

多线程

判断/干活/通知

技术图片
  1 //操作字节码
  2 public class Main
  3 {
  4     public static void main(String[] args)  {
  5         Test02 test = new Test02();
  6 
  7         new Thread(()->{
  8             for(int i = 0; i < 10; i++)
  9                 test.add1();
 10         },"A").start();
 11         new Thread(()->{
 12             for(int i = 0; i < 10; i++)
 13                 test.sub1();
 14         },"B").start();
 15 
 16         new Thread(()->{
 17             for(int i = 0; i < 10; i++)
 18                 test.add1();
 19         },"C").start();
 20         new Thread(()->{
 21             for(int i = 0; i < 10; i++)
 22                 test.sub1();
 23         },"D").start();
 24 
 25 
 26 
 27 
 28     }
 29 }
 30 
 31 class Test02
 32 {
 33 
 34     private int num = 0;
 35     //生产
 36     public synchronized void add1() {
 37         if(num != 0)
 38         {
 39             try {
 40                 wait();
 41             } catch (InterruptedException e) {
 42                 e.printStackTrace();
 43             }
 44         }
 45 
 46         System.out.println(Thread.currentThread().getName() + "线程,当前有" + (num++) + "生产完后" + num);
 47 
 48         notifyAll();
 49 
 50 
 51 
 52     }
 53 
 54     //消费
 55     public synchronized void sub1()
 56     {
 57         if(num == 0)
 58         {
 59             try {
 60                 this.wait();
 61             } catch (InterruptedException e) {
 62                 e.printStackTrace();
 63             }
 64         }
 65 
 66         System.out.println(Thread.currentThread().getName() + "线程,当前有" + (num--) + "消费完之后还有" + num);
 67 
 68         notifyAll();
 69 
 70 
 71     }
 72 
 73 
 74 
 75 }
 76 
 77 /*
 78 A线程,当前有0生产完后1
 79 B线程,当前有1消费完之后还有0
 80 A线程,当前有0生产完后1
 81 B线程,当前有1消费完之后还有0
 82 A线程,当前有0生产完后1
 83 B线程,当前有1消费完之后还有0
 84 A线程,当前有0生产完后1
 85 B线程,当前有1消费完之后还有0
 86 A线程,当前有0生产完后1
 87 B线程,当前有1消费完之后还有0
 88 A线程,当前有0生产完后1
 89 B线程,当前有1消费完之后还有0
 90 C线程,当前有0生产完后1
 91 B线程,当前有1消费完之后还有0
 92 A线程,当前有0生产完后1
 93 B线程,当前有1消费完之后还有0
 94 C线程,当前有0生产完后1
 95 B线程,当前有1消费完之后还有0
 96 A线程,当前有0生产完后1
 97 B线程,当前有1消费完之后还有0
 98 C线程,当前有0生产完后1
 99 A线程,当前有1生产完后2
100 C线程,当前有2生产完后3/////////////
101 A线程,当前有3生产完后4
102 C线程,当前有4生产完后5
103 D线程,当前有5消费完之后还有4
104 D线程,当前有4消费完之后还有3
105 D线程,当前有3消费完之后还有2
106 D线程,当前有2消费完之后还有1/////////////
107 D线程,当前有1消费完之后还有0
108 C线程,当前有0生产完后1
109 D线程,当前有1消费完之后还有0
110 C线程,当前有0生产完后1
111 D线程,当前有1消费完之后还有0
112 C线程,当前有0生产完后1
113 D线程,当前有1消费完之后还有0
114 C线程,当前有0生产完后1
115 D线程,当前有1消费完之后还有0
116 C线程,当前有0生产完后1
117 D线程,当前有1消费完之后还有0
118 
119 */
虚假唤醒

程序的本意是成产一个消费一个,但是这里出现了生产了4,5等数字。

在只存在两个线程(一个负责生产,一个负责消费)时不会出现这种情况,在四个线程(2消费,2生产)时出现这种问题。

这是因为在判断的这个环节使用了if来判断,即两个生产线程都通过if判断,进入里面等待时,一旦唤醒他们直接向下执行,不会再次判断num是否为1。

解决办法:使用while()判断,对个num的值再次判断,决定个线程是否执行。

Study for Test

标签:生产线   ide   private   getname   current   tac   name   消费   trace   

原文地址:https://www.cnblogs.com/chenhebyj/p/11980450.html

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