﻿<?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-我的自留地-文章分类-tech/多线程</title><link>http://www.blogjava.net/lukangping/category/45886.html</link><description>积累。。。沉淀。。。</description><language>zh-cn</language><lastBuildDate>Tue, 07 Sep 2010 15:39:54 GMT</lastBuildDate><pubDate>Tue, 07 Sep 2010 15:39:54 GMT</pubDate><ttl>60</ttl><item><title>并发实践之二：管理线程的四个方法start, sleep, yield, join；线程间协作的方法wait,notify</title><link>http://www.blogjava.net/lukangping/articles/331104.html</link><dc:creator>kangaroo</dc:creator><author>kangaroo</author><pubDate>Sun, 05 Sep 2010 15:06:00 GMT</pubDate><guid>http://www.blogjava.net/lukangping/articles/331104.html</guid><wfw:comment>http://www.blogjava.net/lukangping/comments/331104.html</wfw:comment><comments>http://www.blogjava.net/lukangping/articles/331104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lukangping/comments/commentRss/331104.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lukangping/services/trackbacks/331104.html</trackback:ping><description><![CDATA[<p>刚开始的时候经常会把这两类的方法搞混了，慢慢接触多了，一定要弄清楚了。<br />
(1)管理线程的方法<br />
start：不用多说，启动一个线程的方法。调用该方法后，线程即进入可运行状态，也就是进入可运行的线程池了。<br />
sleep：线程休眠，将一个运行时的线程，将其状态变为可运行状态，然后加入到和其他处于可运行状态下的线程抢夺运行机会。换句话说，sleep的时间是该线程不执行的最短时间。<br />
yield：使得当前线程进入可运行状态，以允许具有相同状态优先级的其他线程获得运行机会。但是不保证，刚进入可运行状态，又被选中进入运行状态。<br />
join：非静态方法join，有点抢线程的意思。一旦某个线程实例t调用join方法，则当前线程变为可运行状态，直到线程t运行完毕为止。<br />
(2)线程间协作的方法</p>
 <img src ="http://www.blogjava.net/lukangping/aggbug/331104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lukangping/" target="_blank">kangaroo</a> 2010-09-05 23:06 <a href="http://www.blogjava.net/lukangping/articles/331104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>并发实践之一：HashMap的非线程安全性和ConcurrentHasMap</title><link>http://www.blogjava.net/lukangping/articles/331089.html</link><dc:creator>kangaroo</dc:creator><author>kangaroo</author><pubDate>Sun, 05 Sep 2010 09:12:00 GMT</pubDate><guid>http://www.blogjava.net/lukangping/articles/331089.html</guid><wfw:comment>http://www.blogjava.net/lukangping/comments/331089.html</wfw:comment><comments>http://www.blogjava.net/lukangping/articles/331089.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/lukangping/comments/commentRss/331089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lukangping/services/trackbacks/331089.html</trackback:ping><description><![CDATA[<p>在平时开发中，我们经常采用HashMap来作为本地缓存的一种实现方式，将一些如系统变量等数据量比较少的参数保存在HashMap中，并将其作为单例类的一个属性。在系统运行中，使用到这些缓存数据，都可以直接从该单例中获取该属性集合。但是，最近发现，HashMap并不是线程安全的，如果你的单例类没有做代码同步或对象锁的控制，就可能出现异常。<br />
<br />
首先看下在多线程的访问下，非现场安全的HashMap的表现如何，在网上看了一些资料，自己也做了一下测试：<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_23_869_Open_Image" onclick="this.style.display='none'; Codehighlighter1_23_869_Open_Text.style.display='none'; Codehighlighter1_23_869_Closed_Image.style.display='inline'; Codehighlighter1_23_869_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_23_869_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_23_869_Closed_Text.style.display='none'; Codehighlighter1_23_869_Open_Image.style.display='inline'; Codehighlighter1_23_869_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;MainClass&nbsp;</span><span id="Codehighlighter1_23_869_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_23_869_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;HashMap</span><span style="color: #000000">&lt;</span><span style="color: #000000">String,&nbsp;String</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;firstHashMap</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;HashMap</span><span style="color: #000000">&lt;</span><span style="color: #000000">String,&nbsp;String</span><span style="color: #000000">&gt;</span><span style="color: #000000">();<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img id="Codehighlighter1_186_866_Open_Image" onclick="this.style.display='none'; Codehighlighter1_186_866_Open_Text.style.display='none'; Codehighlighter1_186_866_Closed_Image.style.display='inline'; Codehighlighter1_186_866_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_186_866_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_186_866_Closed_Text.style.display='none'; Codehighlighter1_186_866_Open_Image.style.display='inline'; Codehighlighter1_186_866_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;InterruptedException&nbsp;</span><span id="Codehighlighter1_186_866_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_186_866_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">线程一</span><span style="color: #008000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #008000"><img id="Codehighlighter1_223_349_Open_Image" onclick="this.style.display='none'; Codehighlighter1_223_349_Open_Text.style.display='none'; Codehighlighter1_223_349_Closed_Image.style.display='inline'; Codehighlighter1_223_349_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_223_349_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_223_349_Closed_Text.style.display='none'; Codehighlighter1_223_349_Open_Image.style.display='inline'; Codehighlighter1_223_349_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t1</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Thread()</span><span id="Codehighlighter1_223_349_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_223_349_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img id="Codehighlighter1_246_345_Open_Image" onclick="this.style.display='none'; Codehighlighter1_246_345_Open_Text.style.display='none'; Codehighlighter1_246_345_Closed_Image.style.display='inline'; Codehighlighter1_246_345_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_246_345_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_246_345_Closed_Text.style.display='none'; Codehighlighter1_246_345_Open_Image.style.display='inline'; Codehighlighter1_246_345_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;run()&nbsp;</span><span id="Codehighlighter1_246_345_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_246_345_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img id="Codehighlighter1_273_340_Open_Image" onclick="this.style.display='none'; Codehighlighter1_273_340_Open_Text.style.display='none'; Codehighlighter1_273_340_Closed_Image.style.display='inline'; Codehighlighter1_273_340_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_273_340_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_273_340_Closed_Text.style.display='none'; Codehighlighter1_273_340_Open_Image.style.display='inline'; Codehighlighter1_273_340_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;i</span><span style="color: #000000">&lt;</span><span style="color: #000000">25</span><span style="color: #000000">;i</span><span style="color: #000000">++</span><span style="color: #000000">)</span><span id="Codehighlighter1_273_340_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_273_340_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstHashMap.put(String.valueOf(i),&nbsp;String.valueOf(i));<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">线程二</span><span style="color: #008000"><br />
</span><span style="color: #008080">17</span><span style="color: #008000"><img id="Codehighlighter1_387_514_Open_Image" onclick="this.style.display='none'; Codehighlighter1_387_514_Open_Text.style.display='none'; Codehighlighter1_387_514_Closed_Image.style.display='inline'; Codehighlighter1_387_514_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_387_514_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_387_514_Closed_Text.style.display='none'; Codehighlighter1_387_514_Open_Image.style.display='inline'; Codehighlighter1_387_514_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t2</span><span style="color: #000000">=</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Thread()</span><span id="Codehighlighter1_387_514_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_387_514_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img id="Codehighlighter1_410_510_Open_Image" onclick="this.style.display='none'; Codehighlighter1_410_510_Open_Text.style.display='none'; Codehighlighter1_410_510_Closed_Image.style.display='inline'; Codehighlighter1_410_510_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_410_510_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_410_510_Closed_Text.style.display='none'; Codehighlighter1_410_510_Open_Image.style.display='inline'; Codehighlighter1_410_510_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&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;run()&nbsp;</span><span id="Codehighlighter1_410_510_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_410_510_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img id="Codehighlighter1_438_505_Open_Image" onclick="this.style.display='none'; Codehighlighter1_438_505_Open_Text.style.display='none'; Codehighlighter1_438_505_Closed_Image.style.display='inline'; Codehighlighter1_438_505_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_438_505_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_438_505_Closed_Text.style.display='none'; Codehighlighter1_438_505_Open_Image.style.display='inline'; Codehighlighter1_438_505_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;j</span><span style="color: #000000">=</span><span style="color: #000000">25</span><span style="color: #000000">;j</span><span style="color: #000000">&lt;</span><span style="color: #000000">50</span><span style="color: #000000">;j</span><span style="color: #000000">++</span><span style="color: #000000">)</span><span id="Codehighlighter1_438_505_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_438_505_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">20</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstHashMap.put(String.valueOf(j),&nbsp;String.valueOf(j));<br />
</span><span style="color: #008080">21</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">22</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">23</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">;<br />
</span><span style="color: #008080">24</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">25</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t1.start();<br />
</span><span style="color: #008080">26</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t2.start();<br />
</span><span style="color: #008080">27</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">28</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">主线程休眠1秒钟，以便t1和t2两个线程将firstHashMap填装完毕。</span><span style="color: #008000"><br />
</span><span style="color: #008080">29</span><span style="color: #008000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.currentThread().sleep(</span><span style="color: #000000">1000</span><span style="color: #000000">);<br />
</span><span style="color: #008080">30</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">31</span><span style="color: #000000"><img id="Codehighlighter1_658_860_Open_Image" onclick="this.style.display='none'; Codehighlighter1_658_860_Open_Text.style.display='none'; Codehighlighter1_658_860_Closed_Image.style.display='inline'; Codehighlighter1_658_860_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_658_860_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_658_860_Closed_Text.style.display='none'; Codehighlighter1_658_860_Open_Image.style.display='inline'; Codehighlighter1_658_860_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;l</span><span style="color: #000000">=</span><span style="color: #000000">0</span><span style="color: #000000">;l</span><span style="color: #000000">&lt;</span><span style="color: #000000">50</span><span style="color: #000000">;l</span><span style="color: #000000">++</span><span style="color: #000000">)</span><span id="Codehighlighter1_658_860_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_658_860_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">32</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">如果key和value不同，说明在两个线程put的过程中出现异常。</span><span style="color: #008000"><br />
</span><span style="color: #008080">33</span><span style="color: #008000"><img id="Codehighlighter1_768_856_Open_Image" onclick="this.style.display='none'; Codehighlighter1_768_856_Open_Text.style.display='none'; Codehighlighter1_768_856_Closed_Image.style.display='inline'; Codehighlighter1_768_856_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_768_856_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_768_856_Closed_Text.style.display='none'; Codehighlighter1_768_856_Open_Image.style.display='inline'; Codehighlighter1_768_856_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">!</span><span style="color: #000000">String.valueOf(l).equals(firstHashMap.get(String.valueOf(l))))</span><span id="Codehighlighter1_768_856_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_768_856_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">34</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.println(String.valueOf(l)</span><span style="color: #000000">+</span><span style="color: #000000">"</span><span style="color: #000000">:</span><span style="color: #000000">"</span><span style="color: #000000">+</span><span style="color: #000000">firstHashMap.get(String.valueOf(l)));<br />
</span><span style="color: #008080">35</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">36</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">37</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #008080">38</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">39</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">40</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
上面的代码在多次执行后，发现表现很不稳定，有时没有异常文案打出，有时则有个异常出现：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/lukangping/20100905.GIF" border="0" /><br />
<br />
为什么会出现这种情况，主要看下HashMap的实现：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_29_581_Open_Image" onclick="this.style.display='none'; Codehighlighter1_29_581_Open_Text.style.display='none'; Codehighlighter1_29_581_Closed_Image.style.display='inline'; Codehighlighter1_29_581_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_29_581_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_29_581_Closed_Text.style.display='none'; Codehighlighter1_29_581_Open_Image.style.display='inline'; Codehighlighter1_29_581_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;V&nbsp;put(K&nbsp;key,&nbsp;V&nbsp;value)&nbsp;</span><span id="Codehighlighter1_29_581_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_29_581_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(key&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">)<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;putForNullKey(value);<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;hash&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;hash(key.hashCode());<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;indexFor(hash,&nbsp;table.length);<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img id="Codehighlighter1_231_494_Open_Image" onclick="this.style.display='none'; Codehighlighter1_231_494_Open_Text.style.display='none'; Codehighlighter1_231_494_Closed_Image.style.display='inline'; Codehighlighter1_231_494_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_231_494_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_231_494_Closed_Text.style.display='none'; Codehighlighter1_231_494_Open_Image.style.display='inline'; Codehighlighter1_231_494_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(Entry</span><span style="color: #000000">&lt;</span><span style="color: #000000">K,V</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;e&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;table[i];&nbsp;e&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;&nbsp;e&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;e.next)&nbsp;</span><span id="Codehighlighter1_231_494_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_231_494_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;k;<br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img id="Codehighlighter1_328_484_Open_Image" onclick="this.style.display='none'; Codehighlighter1_328_484_Open_Text.style.display='none'; Codehighlighter1_328_484_Closed_Image.style.display='inline'; Codehighlighter1_328_484_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_328_484_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_328_484_Closed_Text.style.display='none'; Codehighlighter1_328_484_Open_Image.style.display='inline'; Codehighlighter1_328_484_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(e.hash&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;hash&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;((k&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;e.key)&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;key&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;key.equals(k)))&nbsp;</span><span id="Codehighlighter1_328_484_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_328_484_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;V&nbsp;oldValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;e.value;<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.value&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;value;<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.recordAccess(</span><span style="color: #0000ff">this</span><span style="color: #000000">);<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;oldValue;<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">14</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">15</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">16</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;modCount</span><span style="color: #000000">++</span><span style="color: #000000">;<br />
</span><span style="color: #008080">17</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addEntry(hash,&nbsp;key,&nbsp;value,&nbsp;i);<br />
</span><span style="color: #008080">18</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
</span><span style="color: #008080">19</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
我觉得问题主要出现在方法addEntry，继续看：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">1</span><img id="Codehighlighter1_57_236_Open_Image" onclick="this.style.display='none'; Codehighlighter1_57_236_Open_Text.style.display='none'; Codehighlighter1_57_236_Closed_Image.style.display='inline'; Codehighlighter1_57_236_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_57_236_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_57_236_Closed_Text.style.display='none'; Codehighlighter1_57_236_Open_Image.style.display='inline'; Codehighlighter1_57_236_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;addEntry(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;hash,&nbsp;K&nbsp;key,&nbsp;V&nbsp;value,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;bucketIndex)&nbsp;</span><span id="Codehighlighter1_57_236_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_57_236_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;Entry</span><span style="color: #000000">&lt;</span><span style="color: #000000">K,V</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;e&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;table[bucketIndex];<br />
</span><span style="color: #008080">3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;table[bucketIndex]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Entry</span><span style="color: #000000">&lt;</span><span style="color: #000000">K,V</span><span style="color: #000000">&gt;</span><span style="color: #000000">(hash,&nbsp;key,&nbsp;value,&nbsp;e);<br />
</span><span style="color: #008080">4</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(size</span><span style="color: #000000">++</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;threshold)<br />
</span><span style="color: #008080">5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resize(</span><span style="color: #000000">2</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;table.length);<br />
</span><span style="color: #008080">6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
从代码中，可以看到，如果发现哈希表的大小超过阀值threshold，就会调用resize方法，扩大容量为原来的两倍，而扩大容量的做法是新建一个Entry[]：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080">&nbsp;1</span><img id="Codehighlighter1_29_391_Open_Image" onclick="this.style.display='none'; Codehighlighter1_29_391_Open_Text.style.display='none'; Codehighlighter1_29_391_Closed_Image.style.display='inline'; Codehighlighter1_29_391_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_29_391_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_29_391_Closed_Text.style.display='none'; Codehighlighter1_29_391_Open_Image.style.display='inline'; Codehighlighter1_29_391_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;resize(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;newCapacity)&nbsp;</span><span id="Codehighlighter1_29_391_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_29_391_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;2</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry[]&nbsp;oldTable&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;table;<br />
</span><span style="color: #008080">&nbsp;3</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;oldCapacity&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;oldTable.length;<br />
</span><span style="color: #008080">&nbsp;4</span><span style="color: #000000"><img id="Codehighlighter1_153_226_Open_Image" onclick="this.style.display='none'; Codehighlighter1_153_226_Open_Text.style.display='none'; Codehighlighter1_153_226_Closed_Image.style.display='inline'; Codehighlighter1_153_226_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_153_226_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_153_226_Closed_Text.style.display='none'; Codehighlighter1_153_226_Open_Image.style.display='inline'; Codehighlighter1_153_226_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(oldCapacity&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;MAXIMUM_CAPACITY)&nbsp;</span><span id="Codehighlighter1_153_226_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_153_226_Open_Text"><span style="color: #000000">{<br />
</span><span style="color: #008080">&nbsp;5</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threshold&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;Integer.MAX_VALUE;<br />
</span><span style="color: #008080">&nbsp;6</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />
</span><span style="color: #008080">&nbsp;7</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
</span><span style="color: #008080">&nbsp;8</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
</span><span style="color: #008080">&nbsp;9</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entry[]&nbsp;newTable&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Entry[newCapacity];<br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transfer(newTable);<br />
</span><span style="color: #008080">11</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;table&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;newTable;<br />
</span><span style="color: #008080">12</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threshold&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(</span><span style="color: #0000ff">int</span><span style="color: #000000">)(newCapacity&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;loadFactor);<br />
</span><span style="color: #008080">13</span><span style="color: #000000"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span></div>
<br />
一般我们声明HashMap时，使用的都是默认的构造方法：HashMap&lt;K,V&gt;，看了代码你会发现，它还有其它的构造方法：<font style="background-color: #cce8cc">HashMap(int initialCapacity, float loadFactor)</font>，其中参数initialCapacity为初始容量，loadFactor为加载因子，而之前我们看到的<font style="background-color: #cce8cc">threshold = (int)(capacity * loadFactor);</font> 如果在默认情况下，一个HashMap的容量为16，加载因子为0.75，那么阀值就是12，所以在往HashMap中put的值到达12时，它将自动扩容两倍，如果两个线程同时遇到HashMap的大小达到12的倍数时，就很有可能会出现在将oldTable转移到newTable的过程中遇到问题，从而导致最终的HashMap的值存储异常。<br />
<br />
JDK1.0引入了第一个关联的集合类HashTable，<font face="Arial" color="#333333">它是线程安全的。HashTable的所有方法都是同步的。<br />
JDK2.0引入了HashMap，它提供了一个不同步的基类和一个同步的包装器synchronizedMap。synchronizedMap被称为有条件的线程安全类。<br />
JDK5.0util.concurrent包中引入对Map线程安全的实现ConcurrentHashMap，比起synchronizedMap，它提供了更高的灵活性。同时进行的读和写操作都可以并发地执行。<br />
<br />
所以在开始的测试中，如果我们采用ConcurrentHashMap，它的表现就很稳定，所以以后如果使用Map实现本地缓存，为了提高并发时的稳定性，还是建议使用ConcurrentHashMap。<br />
<br />
<br />
====================================================================<br />
<br />
另外，还有一个我们经常使用的ArrayList也是非线程安全的，网上看到的有一个解释是这样：<br />
一个 ArrayList 类，在添加一个元素的时候，它可能会有两步来完成：1. 在 Items[Size] 的位置存放此元素；2. 增大 Size 的值。<br />
在单线程运行的情况下，如果 Size = 0，添加一个元素后，此元素在位置 0，而且 Size=1；<br />
而如果是在多线程情况下，比如有两个线程，线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停，线程 B 得到运行的机会。线程B也将元素放在位置0，（因为size还未增长），完了之后，两个线程都是size++，结果size变成2，而只有items[0]有元素。<br />
util.concurrent包也提供了一个线程安全的ArrayList替代者CopyOnWriteArrayList。
<pre></span></span></pre>
</span></span><br />
<br />
</font>
<img src ="http://www.blogjava.net/lukangping/aggbug/331089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lukangping/" target="_blank">kangaroo</a> 2010-09-05 17:12 <a href="http://www.blogjava.net/lukangping/articles/331089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>