`
ewon
  • 浏览: 6145 次
  • 来自: ...
最近访客 更多访客>>
社区版块
存档分类
最新评论

一个Java线程死锁的真实案例

    博客分类:
  • Java
阅读更多

前一段时间在做的产品中出现一个BUG,现象是界面起不来,显出Splash Screen后就停在那里。经过分析,调试后发现是传说中的线程死锁。一个已经开发了7,8年的东西,这种问题到现在才无意中暴露出来。

java 代码
  1. public class Main{   
  2.   
  3.     public synchronized void initializeDomainModel() {   
  4.         ApplicationModel model = new ApplicationModel(this);           
  5.       setDomainModel(model);   
  6.           
  7.       model.startSession(name, port, nullnull);   
  8.       model.addPropertyChangeListener(getPanel());   
  9.         try {   
  10.             wait(10000);   
  11.       } catch (InterruptedException e) {   
  12.       }   
  13.     }   
  14. }   
  15.   
  16. public class ApplicationModel extends ...{   
  17.   
  18.   public ApplicationModel(Main m){   
  19.     application = m;   
  20.   }   
  21.   
  22.     public synchronized void startSession(String host, int port,   
  23.                                     String userName, String password) {   
  24.        
  25.         ...    
  26.         applicationInterface.getXXX(this);   
  27.        
  28.     }   
  29.        
  30.        
  31.     public synchronized void serverCallback(Response response, RequestNode node)   
  32.     {   
  33.         
  34.          ...   
  35.          if (application != null) {   
  36.             synchronized(application) {   
  37.                 application.notify();   
  38.             }   
  39.             connectToDb();   
  40.          }   
  41.          ///!   
  42.     }   
  43.        
  44.     public synchronized void addPropertyChangeListener(Listener l){   
  45.     }   
  46.     ...   
  47. }  

程序流程是这样的:

1. Main是程序入口,会启动主界面。 2.  startSession方法中的getXXX(this) 会向Server端发送请求,回调函数serverCallback由另一个线程负责调用。

问题分析:

程序停在36行,说明application,也就是Main对象上的锁没有被主线程释放,而主线程之所以没有走到第10行wait,是因为在第8行addPropertyChangeListener的时候发现其他线程在执行serverCallback占用了ApplicationModel对象的锁。

解决方法:

1。Main中不需要同步整个initializeDomainModel方法,只需要将wait放入同步块即可。 2。调换model.startSession和model.addPropertyChangeListener的顺序也可以解决

 

 

分享到:
评论

相关推荐

    java写的红绿灯演示程序多线程

    总结来说,这个“java写的红绿灯演示程序”是一个理想的实践案例,它展示了Java多线程的基本使用,包括线程的创建、同步、通信和控制。通过分析这个程序,我们可以深入理解J2SE中的并发编程,这对于任何Java开发者来...

    Java 多线程编程中的设计模式~

    2. **观察者模式**:在多线程环境中,观察者模式常用于实现线程间的通信,其中一个对象(主题)的状态改变时会通知所有依赖于它的观察者对象,使得它们能够自动更新自己的状态。 3. **职责链模式**:这种模式可以...

    线程模拟超市购物系统

    总的来说,"线程模拟超市购物系统"是一个很好的学习和实践多线程编程的案例。通过这个系统,我们可以深入理解Java线程的同步、协调机制,以及如何在实际场景中应用这些概念。通过不断优化和改进,我们可以构建出更加...

    JAVA案例开发集锦.rar

    6. **多线程**:Java提供了丰富的多线程支持,案例中可能会介绍Thread类的使用,以及Runnable接口的实现,同时可能涉及到线程同步、互斥锁、死锁等高级话题。 7. **网络编程**:Java的Socket编程是网络应用的基础,...

    基于多线程的电梯运行系统模拟

    总的来说,这个基于多线程的电梯运行系统模拟是一个典型的并发编程案例,展示了如何在Java中利用多线程来处理并发任务,以及如何设计和实现线程间的协作和通信。通过分析和实现这样的项目,开发者可以提升对并发控制...

    大厂真实java高级工程师面试宝典

    除了上述理论知识外,《大厂真实Java高级工程师面试宝典》还提供了大量模拟面试题目及解答,涵盖了算法题、开放性问题等多个方面。通过模拟真实的面试环境,帮助求职者适应紧张气氛,提高应变能力。 #### 五、总结 ...

    JAVA高质量并发详解,多线程并发深入讲解

    - **线程基本概念:** Java线程是程序执行流的最小单元,一个线程包含一个程序计数器(PC)、虚拟机栈、本地方法栈、线程私有的工作内存。 - **线程生命周期:** 包括`NEW`、`RUNNABLE`、`BLOCKED`、`WAITING`、`...

    实战JAVA虚拟机随书源码

    2. 线程死锁:学习如何通过`jstack`命令查看线程状态,识别和解决死锁问题。 3. 类加载器问题:源码可能涉及到双亲委派模型、自定义类加载器等,有助于理解类加载过程及异常处理。 二、JVM性能优化 1. 内存管理:...

    操作系统理发师问题java实现

    ### 操作系统理发师问题Java实现详解 在深入解析给定的代码片段之前,我们先来了解一下“理发师问题”这一经典的操作系统概念。...对于学习操作系统原理和Java编程的人来说,这是一个极佳的学习案例。

    Java Performance_The_Definitive_Guide.zip

    8. **实战案例**:书中包含了许多实际的性能调优案例,通过这些案例,读者可以学习到如何在真实的项目中应用所学的知识,解决性能问题。 综上所述,《Java性能:权威指南》是一本全面而深入的Java性能优化指南,...

    Advanced Programming for Java 2

    本书不仅覆盖了Java 2平台的核心概念和技术细节,还通过一个企业级别的拍卖应用案例来帮助读者掌握如何有效地利用Java API解决实际问题。 #### 二、目标读者 本书面向那些已经具备了一定Java编程基础的开发者,旨在...

    Java Performance Tuning

    9. **实战案例**:分享真实的性能调优场景,提供解决方案和最佳实践。 由于出版商不承担由于使用书中信息而产生的任何错误或遗漏的责任,读者在实际应用中应谨慎对待,并结合实际情况进行调整。此外,书中可能会...

    JAVA课件(东软实训的部分课件,绝对真实!想要的赶紧来下)

    6. **多线程**:Java的并发编程,包括线程的创建、同步、互斥、死锁问题,以及并发工具类(如Semaphore、CountDownLatch、CyclicBarrier等)的使用。 7. **JVM**:Java虚拟机的工作原理,内存模型(堆、栈、方法区...

    张孝祥Java就业培训教程书

    5. **多线程**:Java对并发编程提供了良好的支持,学习者将学习到线程的创建、同步、死锁避免等知识,以及使用并发工具类如ExecutorService、Semaphore等。 6. **网络编程**:Java的Socket编程是实现网络通信的基础...

    Concurrent - Programming in Java.pdf

    - **数据流**:通过管道将数据从一个处理单元传输到另一个。 - **控制流**:控制并发组件之间的交互顺序。 ##### 2. 并行性 - **任务并行**:将一个大任务分解成多个小任务并行处理。 - **数据并行**:对数据的不同...

    最全的java达内笔记

    Java是世界上最流行的编程语言之一,尤其在...总之,"最全的java达内笔记"应是一个全面的学习资源,不仅覆盖EJB,还可能深入到Java的各个方面,旨在帮助学习者构建扎实的Java技能,从而在企业级应用开发中游刃有余。

    Java 工程性能调优教程

    讲解Java多线程环境下的性能问题,如死锁、竞态条件、线程池的合理配置,以及如何通过并发工具类提高并发性能。 4. **模块四:JVM性能监测及调优**(3讲): 深入解析JVM的工作原理,包括垃圾收集器的选择与调优...

    高职Java程序设计课程教学设计与实践.zip

    4. 小组项目:鼓励学生自行构思并实现一个综合性的Java应用,例如模拟银行系统。 五、评估与反馈 通过课堂测验、项目报告、代码评审等方式,全面评估学生的学习成果。同时,教师应及时收集学生反馈,优化教学内容和...

    java学习路线图

    - **多线程技术:** Java支持多线程编程,这一部分将讲解如何在Java中创建和管理线程,理解同步、死锁等概念。 - **Socket网络技术:** Socket是网络通信的基础,本节将讲解如何使用Java进行网络编程。 - **...

Global site tag (gtag.js) - Google Analytics