java怎么拦截某个对象
278
2022-09-14
java:为什么要总是使用对象的notifyAll而不使用notify?
最佳实践:总是使用notifyAll而不使用notify 示例代码:交替打印0和1的程序
package com.example.app;import java.util.Date;public class MyCounter2 { private int counter; public int getCounter() { return counter; } public void setCounter(int counter) { this.counter = counter; } public synchronized void increase(){ String name=Thread.currentThread().getName(); System.out.println(System.currentTimeMillis()+" in thread: "+name+ " "+this.getCounter()); while(this.getCounter()>0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.counter++; System.out.println(System.currentTimeMillis()+" "+name+" "+this.counter); try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } this.notify(); } public synchronized void decrease(){ String name=Thread.currentThread().getName(); System.out.println(System.currentTimeMillis()+" in thread: "+name+ " "+this.getCounter()); while(this.getCounter()<1){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.counter--; System.out.println(System.currentTimeMillis()+" "+name+" "+this.counter); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } this.notify(); }}
package com.example.app;public class NotifyTest2 { private static MyCounter2 myCounter = new MyCounter2(); public static void main(String[] args) throws InterruptedException { Thread t1 = new ThreadA(myCounter); Thread t2= new ThreadB(myCounter); Thread t3=new ThreadC(myCounter); Thread t4 = new ThreadD(myCounter); t1.start(); t2.start(); t3.start(); t4.start(); t1.join(); t2.join(); t3.join(); t4.join(); }}class ThreadA extends Thread{ private MyCounter2 myCounter; public ThreadA(MyCounter2 myCounter){ this.myCounter=myCounter; setName("thread-A"); } @Override public void run(){ while(true){ myCounter.increase(); } }}class ThreadB extends Thread{ private MyCounter2 myCounter; public ThreadB(MyCounter2 myCounter){ this.myCounter=myCounter; setName("thread-B"); } @Override public void run(){ while(true){ myCounter.decrease(); } }}class ThreadC extends Thread{ private MyCounter2 myCounter; public ThreadC(MyCounter2 myCounter){ this.myCounter=myCounter; setName("thread-C"); } @Override public void run(){ while(true){ myCounter.increase(); } }}class ThreadD extends Thread{ private MyCounter2 myCounter; public ThreadD(MyCounter2 myCounter){ this.myCounter=myCounter; setName("thread-D"); } @Override public void run(){ while(true){ myCounter.decrease(); } }}
一次执行结果及执行时序图分析
可见,使用notify时,可能最后4个线程都处于锁对象的等待队列(WaiSet)中,程序阻塞。原因是notify只会唤醒wait set中的1个线程。
将程序中的notify改成notifyAll,就不会出现上述的4个线程都处于wait set中的情况。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~