标签:void 效率 contain time notifyall 不可 ola bre for
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.TimeUnit; 4 5 /** 6 * 创建一个容器,一根线程往里放东西,一根线程判断是否符合条件 7 */ 8 public class MyContainer2 { 9 10 /*volatile*/ List<Object> list = new ArrayList<>(); //内存不可见 11 12 void add(Object o) { 13 try { 14 TimeUnit.SECONDS.sleep(1); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 list.add(o); 19 System.out.println(Thread.currentThread().getName() + " add:" + o); 20 } 21 22 int getSize() { 23 return this.list.size(); 24 } 25 26 public static void main(String[] args) { 27 28 MyContainer2 container = new MyContainer2(); 29 30 new Thread(() -> { 31 for(int i=0; i<10; i++) { 32 container.add("Object" + i); 33 } 34 }, "线程1").start(); 35 36 new Thread(() -> { 37 while (true) { //很浪费cpu资源 38 if(container.getSize() > 5) break; 39 } 40 System.out.println(Thread.currentThread().getName() + "结束"); 41 }, "线程2").start(); 42 } 43 }
看明白接着看,上面代码while(true)很消耗cpu资源,下面代码用到wait和notify,阻塞线程和唤醒线程:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.TimeUnit; 4 5 /** 6 * wait 线程会失去锁 7 * 8 * notify/notifyAll 叫醒线程 不会释放锁 9 * 10 */ 11 public class MyContainer3 { 12 13 volatile List<Object> list = new ArrayList<>(); 14 15 void add(Object o) { 16 try { 17 TimeUnit.SECONDS.sleep(1); 18 } catch (InterruptedException e) { 19 e.printStackTrace(); 20 } 21 list.add(o); 22 System.out.println(Thread.currentThread().getName() + " add:" + o); 23 } 24 25 int getSize() { 26 return this.list.size(); 27 } 28 29 public static void main(String[] args) { 30 31 MyContainer3 container = new MyContainer3(); 32 33 final Object block = new Object(); //锁 34 35 new Thread(() -> { 36 synchronized (block) { 37 System.out.println(Thread.currentThread().getName() + "开始"); 38 if(container.getSize() < 5) { 39 try { 40 System.out.println(Thread.currentThread().getName() + "阻塞"); 41 block.wait(); 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 } 46 System.out.println(Thread.currentThread().getName() + "结束"); 47 } 48 }, "线程2").start(); 49 50 new Thread(() -> { 51 synchronized (block) { 52 for(int i=0; i<10; i++) { 53 container.add("Object" + i); 54 55 if(i > 5) { 56 block.notify(); //当唤醒在block上等待的线程后,线程1并不会失去锁,需要等线程1执行完毕释放锁,线程2才能接着执行。 57 } 58 59 try { 60 TimeUnit.SECONDS.sleep(1); 61 } catch (InterruptedException e) { 62 e.printStackTrace(); 63 } 64 } 65 } 66 }, "线程1").start(); 67 68 } 69 70 }
看明白接着看,上面线程执行效果不理想,下面进行了修改:
import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * wait 失去锁 * * notify/notifyAll 叫醒线程 不会释放锁 * * wait和notify/notifyAll要在synchronized代码块里 * * MyContainer3 改良版 * */ public class MyContainer4 { volatile List<Object> list = new ArrayList<>(); void add(Object o) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } list.add(o); System.out.println(Thread.currentThread().getName() + " add:" + o); } int getSize() { return this.list.size(); } public static void main(String[] args) { MyContainer4 container = new MyContainer4(); final Object block = new Object(); //锁 new Thread(() -> { synchronized (block) { System.out.println(Thread.currentThread().getName() + "开始"); if(container.getSize() < 5) { try { System.out.println(Thread.currentThread().getName() + "阻塞"); block.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + "结束"); block.notify(); //唤醒线程1,继续执行 } }, "线程2").start(); new Thread(() -> { synchronized (block) { for(int i=0; i<10; i++) { container.add("Object" + i); if(container.getSize() == 5) { block.notify(); //当唤醒在block上等待的线程后,线程1并不会失去锁,需要等线程1执行完毕释放锁,线程2才能接着执行。 try { block.wait(); //唤醒线程2,释放掉线程1的锁 } catch (InterruptedException e) { e.printStackTrace(); } } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "线程1").start(); } }
看明白接着看,下面代码用到CountDownLatch,实现上面wait和notify的效果:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.CountDownLatch; 4 import java.util.concurrent.TimeUnit; 5 6 /** 7 * 8 * MyContainer4 改良版 9 * 10 * 较MyContainer4 效率更高 11 * 12 */ 13 public class MyContainer5 { 14 15 volatile List<Object> list = new ArrayList<>(); 16 17 void add(Object o) { 18 try { 19 TimeUnit.SECONDS.sleep(1); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } 23 list.add(o); 24 System.out.println(Thread.currentThread().getName() + " add:" + o); 25 } 26 27 int getSize() { 28 return this.list.size(); 29 } 30 31 public static void main(String[] args) { 32 33 MyContainer5 container = new MyContainer5(); 34 35 //final Object block = new Object(); //锁 36 CountDownLatch latch = new CountDownLatch(5); 37 38 new Thread(() -> { 39 //synchronized (block) { 40 System.out.println(Thread.currentThread().getName() + "开始"); 41 if(container.getSize() < 5) { 42 //try { 43 System.out.println(Thread.currentThread().getName() + "阻塞"); 44 try { 45 latch.await(); //等待门闩打开 46 } catch (InterruptedException e) { 47 e.printStackTrace(); 48 } 49 //block.wait(); 50 //} catch (InterruptedException e) { 51 //e.printStackTrace(); 52 //} 53 } 54 System.out.println(Thread.currentThread().getName() + "结束"); 55 //block.notify(); //唤醒线程1,继续执行 56 //} 57 }, "线程2").start(); 58 59 new Thread(() -> { 60 //synchronized (block) { 61 for(int i=0; i<10; i++) { 62 container.add("Object" + i); 63 64 //if(container.getSize() == 5) { 65 //block.notify(); //当唤醒在block上等待的线程后,线程1并不会失去锁,需要等线程1执行完毕释放锁,线程2才能接着执行。 66 //try { 67 //block.wait(); //唤醒线程2,释放掉线程1的锁 68 //} catch (InterruptedException e) { 69 //e.printStackTrace(); 70 //} 71 //} 72 73 latch.countDown(); //打开门闩,让线程2继续执行 74 75 try { 76 TimeUnit.SECONDS.sleep(1); 77 } catch (InterruptedException e) { 78 e.printStackTrace(); 79 } 80 } 81 //} 82 }, "线程1").start(); 83 84 } 85 86 }
标签:void 效率 contain time notifyall 不可 ola bre for
原文地址:https://www.cnblogs.com/mxh-java/p/12246370.html