当前位置: 首页 > news >正文

建设部网站查询造价师证件柳州网站建设33

建设部网站查询造价师证件,柳州网站建设33,镇江房地产网站建设,昆山市住房和建设局网站1、为什么需要线程的等待和唤醒 线程的等待唤醒机制是一种经典的“生产者和消费者”模型。例如食品加工厂#xff0c;食品加工人员和原料补给人员#xff0c;在有充足原料时#xff0c;补给人员是在等待#xff0c;等到原料不够时#xff0c;食品加工人员通知补给人员食品加工人员和原料补给人员在有充足原料时补给人员是在等待等到原料不够时食品加工人员通知补给人员唤醒。在我们开发诸如此类需求的时候两个线程之间协调等待和唤醒还是很有必要的。那咱们看看都有那些方式实现线程等待和唤醒机制。 2、线程等待和唤醒机制方式  实现线程等待和唤醒机制主要有3中方式分别是 使用 Object 中的 wait() 方法让线程等待使用 Object 中的 notify() 方法唤醒线程使用 JUC 包中 Condition 的 await() 方法让线程等待使用 signal() 方法唤醒线程使用LockSupport类的park()方法让线程等待使用unpark()方法唤醒线程。 那这三种方式具体怎么使用都有那些优缺点呢我们通过实例代码演示。 3、线程等待和唤醒机制实例 3.1、使用 Object 中的 wait() 方法让线程等待使用 Object 中的 notify() 方法唤醒线程 代码 package com.lc.test02;import java.util.concurrent.TimeUnit;/*** author liuchao* date 2023/4/8*/ public class ThreadWaitOne {/*** 注意必须使用同一把锁*/static Object lock new Object();public static void main(String[] args) {/*** 线程1*/Thread t1 new Thread(() - {synchronized (lock) {System.out.println(进入 Thread.currentThread().getName());try {lock.wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println(Thread.currentThread().getName() 被唤醒);}}, t1);t1.start();try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}/*** 线程2*/Thread t2 new Thread(() - {synchronized (lock) {System.out.println(进入 Thread.currentThread().getName());lock.notify();System.out.println(唤醒通知已发);}}, t2);t2.start();} }效果 进入t1 进入t2 唤醒通知已发 t1被唤醒  总结此种方式必须使用同一把锁并且必须包含在synchronized代码块中如果未使用synchronized包裹则会报错。 Exception in thread t1 java.lang.IllegalMonitorStateException     at java.lang.Object.wait(Native Method)     at java.lang.Object.wait(Object.java:502)     at com.lc.test02.ThreadWaitOne.lambda$main$0(ThreadWaitOne.java:24)     at java.lang.Thread.run(Thread.java:750) 并且wait方法的调用必须要在notify/notifyAll的调用之前否则线程将永远不会被唤醒。  3.2、使用 JUC 包中 Condition 的 await() 方法让线程等待使用 signal() 方法唤醒线程 代码 package com.lc.test02;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;/*** author liuchao* date 2023/4/8*/ public class ThreadWaitTwo {/*** 必须是同一把锁*/static Lock lock new ReentrantLock();static Condition condition lock.newCondition();public static void main(String[] args) {/*** 线程1*/Thread t1 new Thread(() - {lock.lock();try {System.out.println(进入 Thread.currentThread().getName());condition.await();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}System.out.println(Thread.currentThread().getName() 被唤醒);}, t1);t1.start();try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}/*** 线程2*/Thread t2 new Thread(() - {lock.lock();try {System.out.println(进入 Thread.currentThread().getName());condition.signal();System.out.println(唤醒通知已发);} finally {lock.unlock();}}, t2);t2.start();} }效果 进入t1 进入t2 唤醒通知已发 t1被唤醒  总结使用此中方式必须配合lock代码必须被lock包裹否则将报错 Exception in thread t1 java.lang.IllegalMonitorStateException     at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)     at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)     at java.util.concurrent.locks.AbstractQueuedSynchronizer.fullyRelease(AbstractQueuedSynchronizer.java:1723)     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2036)     at com.lc.test02.ThreadWaitTwo.lambda$main$0(ThreadWaitTwo.java:28)     at java.lang.Thread.run(Thread.java:750)  并且await方法的调用必须在signal/signalAll方法调用之前否则t1也是不会被唤醒 3.3、使用LockSupport类的park()方法让线程等待使用unpark()方法唤醒线程。   LockSupport 类使用了一种名为 Permit 许可的概念来做到阻塞和唤醒线程的功能每个线程都有一个许可permitpermit 只有两个值 1 和 0默认是 0 阻塞①、park()/park(Object blocker)         ②、permit 默认是 0所以一开始调用 park() 方法当前线程就会阻塞直到别的线程将当前线程的 permit 设置为 1 时park 方法会被唤醒然后会将 permit 再次设置为 0 并返回。         ③、阻塞当前线程/阻塞传入的具体线程 唤醒①、unpark(Thread thread)         ②、调用 unpark(Thread thread) 方法后就会将 thread 线程的许可 permit 设置为 1注意多次调用 unpark 方法不会累加permit 值还是 1会自动唤醒 thread 线程即之前阻塞中的 LockSupport.park()方法会立即返回         ③、唤醒处于阻塞状态的指定线程 代码 package com.lc.test02;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport;/*** author liuchao* date 2023/4/8*/ public class ThreadWaitThree {public static void main(String[] args) {/*** 线程1*/Thread t1 new Thread(() - {System.out.println(进入 Thread.currentThread().getName());LockSupport.park();System.out.println(Thread.currentThread().getName() 被唤醒);}, t1);t1.start();try {TimeUnit.MILLISECONDS.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}/*** 线程2*/Thread t2 new Thread(() - {System.out.println(进入 Thread.currentThread().getName());LockSupport.unpark(t1);System.out.println(唤醒通知已发);}, t2);t2.start();} }效果 进入t1 进入t2 唤醒通知已发 t1被唤醒  结论此种方式不需要增加同步机制天生就是无锁机制实现线程等待和唤醒并且因为是通过许可方式来唤醒线程的所以许可是在等待(调用park()方法)前还是后是不影响的park和unpark调用先后顺序我关此种方式也是我们推荐使用的方式。当然这种方式也是有缺点的许可最多只有一个如果等待多次调用多次park()方法,线程也就永远不能唤醒了。 演示线程的唤醒和unpark先调用还是后调用无关 package com.lc.test02;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport;/*** author liuchao* date 2023/4/8*/ public class ThreadWaitThree {public static void main(String[] args) {/*** 线程1*/Thread t1 new Thread(() - {try {//等待300毫秒让t2先执行TimeUnit.MILLISECONDS.sleep(300);} catch (InterruptedException e) {Thread.currentThread().interrupt();}System.out.println(进入 Thread.currentThread().getName());LockSupport.park();System.out.println(Thread.currentThread().getName() 被唤醒);}, t1);t1.start();/*** 线程2*/Thread t2 new Thread(() - {System.out.println(进入 Thread.currentThread().getName());LockSupport.unpark(t1);System.out.println(唤醒通知已发);}, t2);t2.start();} }效果 进入t2 唤醒通知已发 进入t1 t1被唤醒  演示多次调用unpark多次调用park导致线程不能被唤醒 package com.lc.test02;import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.LockSupport;/*** author liuchao* date 2023/4/8*/ public class ThreadWaitThree {public static void main(String[] args) {/*** 线程1*/Thread t1 new Thread(() - {System.out.println(进入 Thread.currentThread().getName());/*** 调用两次park方法*/LockSupport.park();LockSupport.park();System.out.println(Thread.currentThread().getName() 被唤醒);}, t1);t1.start();try {//等待300毫秒让t2先执行TimeUnit.MILLISECONDS.sleep(300);} catch (InterruptedException e) {Thread.currentThread().interrupt();}/*** 线程2*/Thread t2 new Thread(() - {System.out.println(进入 Thread.currentThread().getName());/*** 调用了两次park我们调用三次unpark 还是无法唤醒t1线程的*/LockSupport.unpark(t1);LockSupport.unpark(t1);LockSupport.unpark(t1);System.out.println(唤醒通知已发);}, t2);t2.start();} }
http://www.hkea.cn/news/14521817/

相关文章:

  • 知名网站建设北京的网站设计
  • 宁夏网站建设一条龙手机制作网站免费
  • 免费的站外推广2021年室内设计公司全国排名百强
  • 网站源代码下载工具什么关键词可以搜到那种
  • 新网站建设的工作各大网站流量排名
  • 手机网站导航栏特效网站排名突然下降解决
  • 蜂蜜做的好网站或案例沈阳新民网站建设
  • 如何制作家具网站网站建设策划书 范文
  • 四川城乡建设网网站昆明优化广告公司
  • 建设网站的价格是多少钱郑州 发布会
  • 购物网站建设课程设计网站开发发送短信
  • 百度推广帮做网站建设厅网站174号文
  • 江苏省建设工人考勤网站在线qq登录无需下载
  • 平顶山北京网站建设自己怎么做网站购买空间
  • 电子商务网站的后台管理系统关键词排名优化公司成都
  • 上海网站建设规划嘉兴网站建设咨询
  • 福田做网站价格网站建设公司公司我我提供一个平台
  • 国际贸易网站有哪些美丽乡村 网站建设
  • 怎么使用wordpress建站wordpress做微信登录页面模板
  • 手机网站开发session邯山手机网站建设
  • 企业网站php模板eclipse怎么做网页
  • 网站建设网站软件有哪些方面设计师互联网
  • 网站设计项目海南网址
  • 动态asp.net网站开发植物染企业解决方案
  • 广州模板网站建设wordpress怎么加栏目
  • 保山市网站建设wordpress开发商
  • 别人恶意点击我们竞价网站中国建设银行舟山分行网站
  • 中企高呈网站建设报考项目经理证需要什么条件
  • 建材 网站 模板洛阳网站建设启辰网络
  • 平度网站建设ld4wordpress主题安装目录