`

Java多线程死锁问题

阅读更多
刚才用jstack解决了一个进程死锁的问题。

流程大致如下:
(0)环境要求,JDK1.6及以上
(1)先找到进程的PID,Windows下,打开进程管理器,按照名字排序,可以找到叫做javaw.exe的进程(java虚拟机进程一律叫做javaw.exe),要找出哪个是你的进程,记住当前进程列表,然后重启你的进程,PID刷新过的那个即是你的进程。
(2)在CMD下运行:jstack pid,jstack会在console上打出一系列信息
(3)分析上述信息

"startQuertz_Worker-2" prio=6 tid=0x000000006201f000 nid=0x14b0 runnable [0x0000000068b9e000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.read(SocketInputStream.java:129)
	at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:97)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:237)
	- locked <0x0000005896b7a708> (a java.io.BufferedInputStream)
	at com.sun.mail.iap.ResponseInputStream.read0(ResponseInputStream.java:81)
	at com.sun.mail.iap.ResponseInputStream.readResponse(ResponseInputStream.java:67)
	at com.sun.mail.iap.Response.<init>(Response.java:83)
	at com.sun.mail.imap.protocol.IMAPResponse.<init>(IMAPResponse.java:48)
	at com.sun.mail.imap.protocol.IMAPResponse.readResponse(IMAPResponse.java:122)
	at com.sun.mail.imap.protocol.IMAPProtocol.readResponse(IMAPProtocol.java:230)
	at com.sun.mail.iap.Protocol.command(Protocol.java:263)
	- locked <0x0000005896b74cb8> (a com.sun.mail.imap.protocol.IMAPProtocol)
	at com.sun.mail.imap.protocol.IMAPProtocol.fetch(IMAPProtocol.java:1234)
	at com.sun.mail.imap.protocol.IMAPProtocol.fetch(IMAPProtocol.java:1226)
	at com.sun.mail.imap.protocol.IMAPProtocol.fetchBody(IMAPProtocol.java:1028)
	at com.sun.mail.imap.protocol.IMAPProtocol.fetchBody(IMAPProtocol.java:1023)
	at com.sun.mail.imap.IMAPInputStream.fill(IMAPInputStream.java:101)
	- locked <0x0000005896bb77d0> (a java.lang.Object)
	at com.sun.mail.imap.IMAPInputStream.read(IMAPInputStream.java:158)
	- locked <0x0000005897da6540> (a com.sun.mail.imap.IMAPInputStream)
	at com.sun.mail.imap.IMAPInputStream.read(IMAPInputStream.java:184)
	at com.sun.mail.util.BASE64DecoderStream.getByte(BASE64DecoderStream.java:337)
	at com.sun.mail.util.BASE64DecoderStream.decode(BASE64DecoderStream.java:230)
	at com.sun.mail.util.BASE64DecoderStream.read(BASE64DecoderStream.java:135)
	at java.io.FilterInputStream.read(FilterInputStream.java:90)
	at javax.mail.internet.MimeBodyPart.saveFile(MimeBodyPart.java:805)
	at com.detao.dtma.email.EmailReciver.processAttachment(EmailReciver.java:244)
	at com.detao.dtma.email.EmailReciver.processMsg(EmailReciver.java:140)
	at com.detao.dtma.email.EmailReciver.processMsg(EmailReciver.java:93)
	at com.detao.dtma.email.EmailReciver.processMessages(EmailReciver.java:69)
	at com.detao.dtma.email.EmailReciver.processMessages(EmailReciver.java:50)
	at com.detao.dtma.email.EmailReciverMgr.run(EmailReciverMgr.java:31)
	at sun.reflect.GeneratedMethodAccessor2511.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
	at org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean$MethodInvokingJob.executeInternal(MethodInvokingJobDetailFactoryBean.java:264)
	at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:86)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)

"startQuertz_Worker-1" prio=6 tid=0x0000000064022800 nid=0x3a4 waiting for monitor entry [0x0000000068a9f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000005872f40648> (a java.lang.Object)
	at org.quartz.simpl.SimpleThreadPool.getNextRunnable(SimpleThreadPool.java:428)
	- locked <0x0000005872f40648> (a java.lang.Object)
	at org.quartz.simpl.SimpleThreadPool.access$000(SimpleThreadPool.java:47)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:518)

"startQuertz_Worker-0" prio=6 tid=0x0000000060f15000 nid=0x13e8 waiting for monitor entry [0x000000006899f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.lang.Object.wait(Native Method)
	- waiting on <0x0000005872f40648> (a java.lang.Object)
	at org.quartz.simpl.SimpleThreadPool.getNextRunnable(SimpleThreadPool.java:428)
	- locked <0x0000005872f40648> (a java.lang.Object)
	at org.quartz.simpl.SimpleThreadPool.access$000(SimpleThreadPool.java:47)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:518)

"Store userCache Spool Thread" daemon prio=6 tid=0x000000006194f000 nid=0x1354 waiting on condition [0x000000006889f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
	at java.lang.Thread.sleep(Native Method)
	at net.sf.ehcache.store.DiskStore.spoolAndExpiryThreadMain(DiskStore.java:634)
	at net.sf.ehcache.store.DiskStore.access$900(DiskStore.java:68)
	at net.sf.ehcache.store.DiskStore$SpoolAndExpiryThread.run(DiskStore.java:1110)


最后定位到错误行
at com.detao.dtma.email.EmailReciverMgr.run(EmailReciverMgr.java:31)

找到相应代码
public class EmailReciverMgr extends TimerTask {
	/* 邮件接收器 一个邮件接收器对应一个邮箱 */
	private java.util.List<EmailReciver> recivers;
	/* 程序是否正在进行 */
	private boolean running = false;

	public void setRecivers(java.util.List<EmailReciver> recivers) {
		this.recivers = recivers;
	}

	@Override
	public void run() {
		// 如果正在运行就返回,否则运行
		if (running) {
			return;
		}
		try {
			running = true;
			// 循环邮件接收器 
			for (EmailReciver reciver : recivers) {
				// 处理邮件
				reciver.processMessages();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 运行完毕设置为false,以便进行下一次运行
			running = false;
		}

	}
}

程序本身没有问题,问题出现在了调用上,两个定时器都有自己的定时策略,分别调用了两次,造成相互等待,形成死锁。

此问题的难点在于问题的定位,问题的发生具有不确定性,有时候半月不发生,有时候一天发生多次,定位不到问题,后台没有任何报错,最后jstack,终于定位到了问题,找到问题之后,解决就好办了。
分享到:
评论

相关推荐

    java多线程死锁预防机制研究

    ### Java多线程死锁预防机制研究 #### 摘要 随着计算机技术的发展和软件系统日益复杂的背景下,多线程编程技术得到了广泛的应用。多线程能够显著提高程序的执行效率,但也随之带来了诸如死锁等问题。死锁是指两个或...

    java模拟线程死锁

    线程死锁是 Java 编程中的一种常见的问题,它可以导致程序的崩溃或性能下降。为了避免线程死锁,我们需要在设计线程之间的交互时,遵循一定的规则和原则,例如避免循环等待、使用锁对象和线程通信机制。

    多线程死锁

    明白死锁产生的原因,在程序中演示死锁产生并从而实现多线程陈旭解决死锁(deadlock)这一类问题。

    Java多线程程序死锁检查 JCarder

    总之,理解和掌握Java多线程中的死锁问题及其解决方案是每个Java开发者必备的技能。通过使用JCarder这样的工具,我们可以更加高效地调试和优化多线程程序,确保其在高并发环境下的正确性和稳定性。

    Java Swing多线程死锁问题解析

    Java Swing多线程死锁问题解析 Java Swing多线程死锁问题解析是Java开发者经常遇到的问题之一。在基于Java Swing进行图形界面开发时,经常会遇到多线程问题。如果在图形界面的同一个线程中进行查询和运算工作,则会...

    多线程死锁问题

    在Java多线程编程中,死锁是一个非常重要的概念,也是开发者需要密切关注和避免的问题。死锁是指两个或多个线程互相等待对方释放资源,从而导致它们都无法继续执行的状态。这种情况通常发生在并发环境中,当线程间的...

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    Java多线程死锁示例

    在本示例中,我们将深入探讨Java多线程死锁的概念,并通过一个具体的代码示例来理解其工作原理和避免策略。 首先,我们来看标题中的关键点——“Java多线程死锁示例”。死锁是多线程编程中的一种异常状态,通常发生...

    汪文君JAVA多线程编程实战(完整不加密)

    《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...

    java多线程经典案例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,极大地提升了程序的效率和性能。在Java中,实现多线程有两种主要方式:通过实现Runnable接口或者继承Thread类。本案例将深入探讨Java多线程中的关键...

    JAVAJAVA多线程教学演示系统论文

    《JAVA多线程教学演示系统》是一篇深入探讨JAVA多线程编程的论文,它针对教育领域中的教学需求,提供了一种生动、直观的演示方式,帮助学生更好地理解和掌握多线程技术。这篇论文的核心内容可能包括以下几个方面: ...

    JAVA源码Java多线程程序死锁检查JCarder

    JAVA源码Java多线程程序死锁检查JCarder

    JAVA多线程编程技术PDF

    总结起来,“JAVA多线程编程技术PDF”涵盖了多线程的基本概念、同步机制、线程通信、死锁避免、线程池以及线程安全的集合类等内容。通过深入学习这份资料,开发者可以全面掌握Java多线程编程技术,提升程序的并发...

    java 多线程并发实例

    另外,可能还会涉及到死锁、活锁和饥饿等并发问题,这些都是多线程编程中需要特别关注的。例如,死锁发生在两个或更多线程互相等待对方释放资源,导致它们都无法继续的情况。避免死锁的方法包括避免循环等待、设置...

    Java多线程编程核心技术_完整版_java_

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

    基于java的开发源码-多线程程序死锁检查 JCarder.zip

    基于java的开发源码-多线程程序死锁检查 JCarder.zip 基于java的开发源码-多线程程序死锁检查 JCarder.zip 基于java的开发源码-多线程程序死锁检查 JCarder.zip 基于java的开发源码-多线程程序死锁检查 JCarder.zip ...

    Java多线程程序死锁检查 JCarder.7z

    JCarder是一款用于检测Java多线程程序中死锁问题的工具,它可以帮助开发者识别和解决这类问题,确保程序的稳定运行。 首先,了解Java多线程中的死锁。在Java中,死锁通常发生在多个线程各自持有某些资源,并且都...

    java资源Java多线程程序死锁检查JCarder

    java资源Java多线程程序死锁检查 JCarder提取方式是百度网盘分享地址

    java源码:Java多线程程序死锁检查 JCarder.zip

    总之,理解和掌握Java多线程中的死锁问题至关重要,而JCarder这样的工具可以帮助开发者更好地诊断和解决这些问题,提高软件的稳定性和性能。通过深入学习并实践这些知识,可以提升你在Java并发编程领域的专业能力。

Global site tag (gtag.js) - Google Analytics