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

建设部网站查询造价师证件长垣县建站塔山双喜

建设部网站查询造价师证件,长垣县建站塔山双喜,给一个公司做网站需要多久,excel如何做超链接网站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.eeditor.cn/news/119989/

相关文章:

  • 湛江住房和城乡建设部网站免费企业官网怎么做
  • 网站备案需要把网站做好吗建英文网站费用
  • 仿淘宝商城网站开源系统做网站模板和服务器是一样的吗
  • 昆网站在哪里html个人网页设计代码
  • 做网站网站怎么赚钱用php做商城网站的设计论文
  • 响应式博客网站模板建设酒店网站ppt模板下载
  • 做论坛网站需要什么备案大连网络代运营
  • 网站怎么做搜索功能网站开发怎么自动获取位置
  • 单页网站seo阜阳做网站有吗
  • 百色建设局网站wordpress主题的安装
  • 电子商务旅游网站建设策划书学it去哪里学比较好
  • 装饰公司网站设计昆山公司网站建设电话
  • 邢台医院网站建设怎么注册一个企业邮箱
  • 温州营销网站公司哪家好篮球网站建设目标
  • 手机音乐网站程序源码南京触屏网站开发
  • html 旅游网站三维动画制作
  • 如何做网站详细步骤图搭建 网站 实例
  • 太原网站制作在线长沙房地产公司有哪些
  • 河南网站建设价格大全手机网站如何开发
  • 办公门户网站模板下载网站制作里的更多怎么做
  • wordpress 小程序专业的网站优化公司排名
  • 有没有做专利导航运营的网站桂林两江四湖在哪里
  • 中山手机网站建设青岛缤纷网络科技有限公司
  • flash网站引导页wordpress获取链接地址
  • 微网站建设公司厦门建设局网站改到哪
  • 洛阳专业做网站多少钱网站建设十年经验
  • 怎们自己做网站莱芜金点子最新招工
  • 自己做网站怎么跳过备案wordpress安装包
  • 蜗牛星际做网站怎么制作网站教程电商
  • 建收费网站网页界面设计要中重点掌握