0

0

线程等待和释放的小麻烦(wait/notify)

php中文网

php中文网

发布时间:2016-06-07 17:45:38

|

1149人浏览过

|

来源于php中文网

原创

class threada extends thread{

  //线程同步的公共数据区

  Object oa=null;

  ThreadA(Object o){

  this.oa=o;

  }

  //线程A执行逻辑

  public void run(){

  //线程同步区域,需要申请公共数据的锁

  synchronized(oa){

  System.out.println("ThreadA is running......");

  for(int i=0;i

  System.out.println("   ThreadA value is "+i);

  if(i==50){

  try {

  //当前线程等待

  Thread.currentThread().wait();

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }//if(i==50)

  }//for(int i)

  }

  }

  }

  /**

  *  线程B:等待线程A放弃锁,然后获得锁并执行,完成后唤醒线程A

  */

  class ThreadB extends Thread{

  //线程同步的公共数据区

  Object ob=null;

  ThreadB(Object o){

  this.ob=o;

  }

  //线程B执行逻辑

  public void run(){

  //线程同步区域,需要申请公共数据的锁

  synchronized(ob){

  System.out.println("ThreadB is running......");

  for(int i=0;i

  System.out.println("   ThreadB value is "+i);

大师兄智慧家政
大师兄智慧家政

58到家打造的AI智能营销工具

下载

  }

  

  //唤醒等待的线程

  notify();

  }

  }

  }

  //测试

  public class ThreadTest {

  public static void main(String[] args){

  Object lock=new Object(); //公共数据区

  ThreadA threada=new ThreadA(lock);

  ThreadB threadb=new ThreadB(lock);

  threada.start(); //线程A执行

  threadb.start(); //线程B执行

  }

  }       程序很简单,就是让线程A,B交替打印。但是运行的时候会抛出两个异常:

  Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread not owner

  Exception in thread "Thread-1" java.lang.IllegalMonitorStateException: current thread not owner

  问题就处在ThreadA中的Thread.currentThread().wait(); 和ThreadB中的notify();上。

  初学者理解wait()的时候都认为是将当前线程阻塞,所以Thread.currentThread().wairt();视乎很有道理。但是不知道大家有没有发现,在JDK类库中wait()和notify()方法并不是Thread类的,而是Object()中的。我们仔细看看wait方法的JDK文档:

  public final void wait() throws InterruptedException

  Object (Java 2 Platform SE 6) <script type="text/"> function windowTitle() { if (location.href.indexOf('is-external=true') == -1) { parent.document.title="Object (Java 2 Platform SE 6)"; } } </script>

  

  在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。

  当前线程必须拥有此 对象监视器 。该线程发布对此监视器的所有权并等待 ,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。 然后该线程将等到重新获得对监视器的所有权后才能继续执行。

  对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:

  synchronized (obj) {

  while ()

  obj.wait();

  // Perform action appropriate to condition

  }

  此方法只应由作为此对象监视器的所有者的线程来调用。

  抛出: IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。

  InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

  看完JDK文档以后,很显然,只要把开始的程序中Thread.currentThread().wait();改成oa.wait() 。 notify();改成 ob.notify()就没有问题了。

  也就是说,只能通过同步块obj来调用wait/notify方法 ,而不能通过想当然的线程调用这两个方法。至于为什么是这样,我有一种想法,大家可以一起讨论一下:

  首先,我们都知道JVM会给每一个对象都分配唯一的一把锁。这把锁是在对象中的。

  然后,当Thread-0线程获得了这把锁后,应该是在对象中的锁内记录下当前占有自己的线程号,并把自己设置为已被占用。那么当Thread-0需要放弃锁的时候,锁对象会吧 Thread-0放入到锁的等待队列中 。而这一切和Thread-0是没有任何关系的。自然也轮不到Thread-0对象来调用某个方法来改变另一个对象中的锁(这一点也说不通,我自己的锁凭什么让你来改)。

相关文章

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

1044

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

334

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

213

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

35

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

111

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

77

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

17

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

813

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

97

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 18.5万人学习

Pandas 教程
Pandas 教程

共15课时 | 1.1万人学习

C# 教程
C# 教程

共94课时 | 10万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号