﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-永恒瞬间-随笔分类-java</title><link>http://www.blogjava.net/cdredfox/category/43085.html</link><description>一个小小程序员的信口开河</description><language>zh-cn</language><lastBuildDate>Sat, 30 Jul 2011 15:37:21 GMT</lastBuildDate><pubDate>Sat, 30 Jul 2011 15:37:21 GMT</pubDate><ttl>60</ttl><item><title>一则多线程死锁案例解析</title><link>http://www.blogjava.net/cdredfox/archive/2011/07/26/355050.html</link><dc:creator>永恒瞬间</dc:creator><author>永恒瞬间</author><pubDate>Tue, 26 Jul 2011 04:44:00 GMT</pubDate><guid>http://www.blogjava.net/cdredfox/archive/2011/07/26/355050.html</guid><wfw:comment>http://www.blogjava.net/cdredfox/comments/355050.html</wfw:comment><comments>http://www.blogjava.net/cdredfox/archive/2011/07/26/355050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/cdredfox/comments/commentRss/355050.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/cdredfox/services/trackbacks/355050.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; font-size: 10pt; ">上周，我们有几个系统发生了线程死锁，导致系统的请求被挂住，无法响应请求。后面查了一下该问题，原来是我厂一个基础组件中使用的锁对象不一致而导致了死锁。</span><span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; "><br /><font class="Apple-style-span" color="#555555"><span class="Apple-style-span" style="font-size: 12px;"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;SimpleStore&nbsp;{<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;Map&nbsp;sessions&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Collections.synchronizedMap(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;HashMap());<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;remove(String&nbsp;sessionID)&nbsp;{&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">A1</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sessions.put(sessionID,&nbsp;</span><span style="color: #000000; ">""</span><span style="color: #000000; ">);&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">A2</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sessions.remove(sessionID);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">remove&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;sessionID);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;commit(Map&nbsp;attrs,&nbsp;String&nbsp;sessionID,&nbsp;StatusHolder&nbsp;statusHolder)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">commit&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">+</span><span style="color: #000000; ">&nbsp;sessionID);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;(sessions)&nbsp;{&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">B1</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;remove(sessionID);&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;B2</span><span style="color: #008000; "><br /></span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;}</span></div></span></font></span><span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; font-size: 10pt; ">上面代码中：</span><span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; "><br /><font class="Apple-style-span" color="#555555"><span class="Apple-style-span" style="font-size: 12px;"><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;Map&nbsp;sessions&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;Collections.synchronizedMap(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;HashMap());</span></div></span></font></span><p><span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; font-size: 10pt; ">将sessions这个map申明为线程安全的map,则操作map中的任何方法时，都会加锁，并且会锁住sessions对象。</span><span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; ">&nbsp;&nbsp;</span><span class="Apple-style-span" style="font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; line-height: 17px; font-size: 10pt; ">这行代码，则在外部线程访问remove方法时会锁住SimpleStore这个对象。<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">synchronized</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;remove(String&nbsp;sessionID);</span></div></span></p><p style="color: #555555; font-size: 12px; "><span style="color: #000000; font-size: 10pt; ">可以看到，目前在同一个类或者方法中，有两把锁，并且锁对象不是同一个，那下面我们看看线程是怎么被死锁住的：<br /></span><span style="color: #000000; font-size: 10pt; ">1, 假设A线程先调用remove方法，则这时会把simpleStore给锁住，然后执行sessions.put(sessionID, &#8220;&#8221;)的时候，会尝试锁住sessions<br /></span><span style="color: #000000; font-size: 10pt; ">2, 同时B线程调用commit方法，在 synchronized (sessions) 时，会先锁住sessions对象，并且在调用接下来的remove()试，会尝试锁住&nbsp; &nbsp;SimpleStore对象，至此，线程A和线程B终于成功完成死锁。</span></p><p>&nbsp;</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; text-indent: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; "><span style="color: #000000; font-size: 10pt; ">所以在使用多线程时一定要特别注意，使用锁一定要注意你的锁对象是否一致。要不然就有可能死锁了~</span></p><span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; "></span><span class="Apple-style-span" style="color: #555555; font-family: Verdana, 'BitStream vera Sans', Tahoma, Helvetica, sans-serif; font-size: 12px; line-height: 17px; "><br /><br /><br /></span><img src ="http://www.blogjava.net/cdredfox/aggbug/355050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/cdredfox/" target="_blank">永恒瞬间</a> 2011-07-26 12:44 <a href="http://www.blogjava.net/cdredfox/archive/2011/07/26/355050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>