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

南宁庆云网站建设凡科建站公司

南宁庆云网站建设,凡科建站公司,新网站一般多久收录,生产企业做网站有用吗写在前面:无论是调用哪种等待和唤醒的方法,都必须是当前线程所持有的对象,否则会导致 java.lang.IllegalMonitorStateException 等并发安全问题。 以三个线程循环打印 XYZ 为例。 一、方法 1.1 Object 对象锁 可以通过 synchronized 对方…

写在前面:无论是调用哪种等待和唤醒的方法,都必须是当前线程所持有的对象,否则会导致 java.lang.IllegalMonitorStateException 等并发安全问题。

以三个线程循环打印 XYZ 为例。

一、方法

1.1 Object 对象锁

可以通过 synchronized 对方法、对象实例、类加锁,并调用加锁对象的 Object#wait() (会释放线程持有的锁)和 Object#notify() 方法等待和唤醒线程。

class Main {// 打印次数private static final int times = 10;// 下一个打印的字母类型private static volatile int type = 0;public static void main(String[] args) {for (int i = 0; i < 3; i++) {int v = i;new Thread(() -> print(v)).start();}}/*** curType:当前线程打印的类型* 对静态方法加锁,锁住的是类本身*/private static synchronized void print(int curType) {for (int i = 0; i < times; ) {try {// 如果当前类型不是自己的类型,则等待while (type != curType) {Main.class.wait();}char c = (char) ('X' + curType);System.out.print(c);type = (type + 1) % 3;i++;// 唤醒全部线程Main.class.notifyAll();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

1.2 Lock#Condition 类

Condition 类与 Lock 类配合使用,允许多个 Condition 和一个 Lock 关联,提供了更加灵活强大的线程同步机制。

class Main {// 打印次数private static final int times = 10;// 下一个打印的字母类型private static volatile int type = 0;private static Lock lock = new ReentrantLock();private static Condition[] conditions = new Condition[3];static {for (int i = 0; i < 3; i++) {conditions[i] = lock.newCondition();}}public static void main(String[] args) {for (int i = 0; i < 3; i++) {int v = i;new Thread(() -> print(v)).start();}}/*** curType:当前线程打印的类型*/private static void print(int curType) {for (int i = 0; i < times; ) {lock.lock();try {// 如果当前类型不是自己的类型,则等待while (type != curType) {conditions[curType].await();}char c = (char) ('X' + curType);System.out.print(c);type = (type + 1) % 3;i++;// 唤醒下一个线程conditions[type].signal();} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {lock.unlock();}}}
}

1.3 Semaphore

1.4 CyclicBarrier

1.5 CountDownLatch

二、注意事项

2.1 虚假唤醒

class Main {// 打印次数private static final int times = 10;// 下一个打印的字母类型private static volatile int type = 0;public static void main(String[] args) {Main1 main = new Main1();for (int i = 0; i < 3; i++) {int v = i;new Thread(() -> main.print(v)).start();}}private synchronized void print(int curType) {for (int i = 0; i < times; ) {try {// 如果当前类型不是自己的类型,则等待if (type != curType) {wait();}char c = (char) ('X' + curType);System.out.print(c);type = (type + 1) % 3;i++;// 唤醒全部线程notifyAll();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}

大家可以执行一下这段代码,会发现打印出来的结果是乱序的,问题的原因就是发生了虚假唤醒。

所谓虚假唤醒,指的是线程在没有满足唤醒条件的情况下被唤醒,发生的原因(排除自身代码逻辑问题)主要是内核线程调度器的调度策略不当(出于性能和效率的考量,会提前唤醒某些线程)。

而只需要把这里改成 while 循环,在线程被唤醒后再检查一遍是否满足唤醒条件即可。

while (type != curType) {wait();
}

2.2 IllegalMonitorStateException 异常原因

调用等待和唤醒方法的线程没有持有对应的锁。

// 正确
Object lock = new Object();
synchronized(lock){lock.wait();
}// 错误,this.wait() 关联的是当前对象实例的锁,而不是 lock 实例
// 当前线程并未对当前对象实例加锁,抛出 IllegalMonitorStateException 异常
Object lock = new Object();
synchronized(lock){this.wait();
}

http://www.dtcms.com/wzjs/570313.html

相关文章:

  • 网站部分链接做301跳转茶叶市场网站建设方案
  • 网站设计有哪几种设计方法wordpress nginx配置伪静态
  • 网站建设要考虑哪些百度网盘官方网站
  • 怎么做挖矿网站郑州最新情况
  • 网站建设运营知识四川建设人才网官网
  • 牧和邻宠物网站建设怎么推广自己做的网站吗
  • 白银市建设局网站一级消防工程师考试题型
  • 京东可以免费做特效的网站网页开发公司网站
  • 百度快照和做网站有关系吗潮州市建设工程交易中心网站
  • 射阳建设局网站公司集团网站建设
  • 建设网站要多少费用生态文明建设网站专题培训
  • 下载网站模板怎么使用服务器网站建设维护
  • 全网黄页网站网站建设公司无锡
  • 宜春市建设局网站自己做短视频的网站
  • 建设部网站1667号如何查看网站开发语言
  • 如何用自己的电脑建网站石河子网站建设
  • 集约化网站群建设内容自己做的网站能赚钱吗
  • 青岛高品质网站制作南宁cms建站
  • 网页就是一个网站的首页邢台封控最新消息
  • 京东网站建设的基本情况口碑营销的形式
  • 网站制作公司 沈阳平面设计师兼职网站
  • 湖北网站建设公司排名网站服务器租赁哪家好
  • 网站老是快照打开wordpress插件安装目录下
  • 辽宁响应式网站建设价格wordpress 插件
  • 济南君哲网站建设公司浙江省住房和城乡建设厅 官方网站
  • 网站服务器怎么重启图片上加语音 网站开发
  • 镜像网站是如何做的阿里云wordpress托管
  • 网红网站建设官网重庆专业seo
  • 自已电脑做网站服务器企业网站设计营销
  • 无锡专业网站制作的公司企业网站开发价钱低