大家不用關(guān)心程序?qū)嶋H邏輯是否正確,只是好奇,為什么這個(gè)程序會(huì)hang住不運(yùn)行了?而且CPU會(huì)占用100%

          import java.util.HashMap;

          public class TestLock {

          private HashMap map = new HashMap();

          public TestLock() {
          Thread t1 
          = new Thread() {
          public void run() {
          for(int i=0; i<50000; i++) {
          map.put(
          new Integer(i), i);
          }
          System.out.println(
          "t1 over");
          }
          };

          Thread t2 
          = new Thread() {
          public void run() {
          for(int i=0; i<50000; i++) {
          map.put(
          new Integer(i), i);
          }

          System.out.println(
          "t2 over");
          }
          };


          t1.start();
          t2.start();

          }


          public static void main(String[] args) {    
          new TestLock();
          }
          }


          Dump thread會(huì)看到,程序hang到:

          "Thread-1" prio=6 tid=0x00c70bd8 nid=0x914 runnable [0x02ebf000..0x02ebfc68]
          at java.util.HashMap.put(HashMap.java:420)
          at TestLock$2.run(TestLock.java:20)

          "Thread-0" prio=6 tid=0x00c70a50 nid=0x578 runnable [0x02e7f000..0x02e7fb68]
          at java.util.HashMap.put(HashMap.java:420)
          at TestLock$1.run(TestLock.java:11)

          Feedback

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 17:53 by nobody
          HashMap 不是線程安全的;請(qǐng)換成Hashtable。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 18:23 by Scud(飛云小俠)
          我在本地運(yùn)行了一下 沒(méi)發(fā)現(xiàn)死鎖.

          你可以用visualvm 檢測(cè)一下, 它可以發(fā)現(xiàn)是否死鎖, 已經(jīng)死鎖的行數(shù)等信息

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 20:07 by stone2083
          "Thread-1" prio=6 tid=0x00c70bd8 nid=0x914 runnable
          兩個(gè)線程都是runnable狀態(tài).

          這程序,理論上,不應(yīng)該出現(xiàn)死鎖的.

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?[未登錄](méi)  回復(fù)  更多評(píng)論   

          2010-08-04 20:39 by 行云流水
          不會(huì)發(fā)生死鎖。不是線程安全的hashmap,貌似你也沒(méi)有用到鎖的概念。只是到最后map里面的數(shù)據(jù)大于50000.

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 21:02 by 天快黑了
          @nobody
          這個(gè)知道,現(xiàn)在是想搞明白程序?yàn)槭裁磿?huì)hang在那不走了

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 21:03 by 天快黑了
          @Scud(飛云小俠)
          應(yīng)該是與機(jī)器有關(guān),我公司機(jī)器,使用300個(gè)循環(huán)就會(huì)hang,你可以試著把循環(huán)調(diào)大一點(diǎn)試試看。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 21:30 by stone2083
          突然記起來(lái)了.請(qǐng)參考這篇文章:
          http://sdh5724.javaeye.com/blog/619130

          在自己電腦上,一直無(wú)法重現(xiàn)這個(gè)問(wèn)題(無(wú)論加大循環(huán),或者增加線程數(shù)),明天回公司再去看看.

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-04 22:02 by 天快黑了
          @stone2083
          非常感謝提供的鏈接。

          對(duì),可能是多個(gè)線程同時(shí)修改HashMap,導(dǎo)致,HashMap內(nèi)部死循環(huán)了。不過(guò)奇怪,不管怎么dump thread,都是hang在HashMap.java:420,而查看HashMap的代碼,怎么也想不通這個(gè)地方會(huì)hang住。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 09:37 by peacess
          線程還在運(yùn)行,而main函數(shù)已經(jīng)退了,

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 10:50 by 豬兒笨笨
          你在put方法420行的循環(huán)中 加一句
          System.out.println(e+" "+e.next);

          就會(huì)產(chǎn)生一個(gè)死循環(huán),即e=e.next.next。
          應(yīng)該是多線程下,進(jìn)行hash處理的時(shí)候出現(xiàn)的。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 12:31 by 天快黑了
          @豬兒笨笨
          e.next訪問(wèn)的是e的一個(gè)屬性,怎么會(huì)相當(dāng)于e.next.next?

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 19:06 by bigwesthorse
          我改成了concurrenthashmap還是會(huì)出現(xiàn),只是出現(xiàn)的頻率降低了不少,大家可以陸續(xù)開(kāi)上千個(gè)進(jìn)程試一下
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          start javaw TestLock
          ...........etc

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 19:13 by bigwesthorse
          @bigwesthorse
          只有hashtable可以順利地通過(guò)1429個(gè)進(jìn)程測(cè)試,哈哈,似乎看到了一點(diǎn)讓人驚喜的東西

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?[未登錄](méi)  回復(fù)  更多評(píng)論   

          2010-08-05 20:58 by kafka0102
          死循環(huán)的代碼在hashmap的transfer方法:
          void transfer(final Entry[] newTable) {
          final Entry[] src = table;
          final int newCapacity = newTable.length;
          final long time1 = System.currentTimeMillis();
          for (int j = 0; j < src.length; j++) {
          Entry<K,V> e = src[j];
          if (e != null) {
          src[j] = null;
          do {
          final Entry<K,V> next = e.next;
          final int i = indexFor(e.hash, newCapacity);
          e.next = newTable[i];
          newTable[i] = e;
          e = next;
          } while (e != null);
          }
          }
          }
          我的分析是:死循環(huán)就在while中,對(duì)同一個(gè)舊table中的e,一個(gè)線程執(zhí)行了 e.next = newTable[i];(還沒(méi)到 e = next;),另一個(gè)才到 final Entry<K,V> next = e.next;,結(jié)果后到的線程接著執(zhí)行e = next;造成e=e.next,死循環(huán)了。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 22:00 by 豬兒笨笨
          樓上的
          不是e=e.next
          而是e=e.next.next
          不過(guò)你的分析應(yīng)該是對(duì)的,就是在根據(jù)hashcode計(jì)算位置的時(shí)候,因?yàn)椴l(fā)的原因出現(xiàn)問(wèn)題了。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 22:01 by 豬兒笨笨
          @天快黑了

          這個(gè)很正常的,因?yàn)閑.next相當(dāng)于一個(gè)鏈表指針,指向下一個(gè)點(diǎn),它們是同一個(gè)例的實(shí)類。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 22:03 by 豬兒笨笨
          另外,關(guān)于HashMap的實(shí)現(xiàn),已經(jīng)說(shuō)了是線程不安全的,多線程下,出現(xiàn)問(wèn)題是正常的。

          Hashtable一直線程安全,可以放心用。
          但說(shuō)concurrenthashmap不對(duì),這個(gè)應(yīng)該不會(huì)。
          回頭也試一下再來(lái)討論。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-05 22:38 by 豬兒笨笨
          用了concurrenthashmap,循環(huán)5000次,沒(méi)有出現(xiàn)問(wèn)題。

          public TestLock() {


          for (int i = 0; i < 5000; i++) {

          final int count=i;

          Thread t1 = new Thread() {
          public void run() {
          for (int i = 0; i < 50000; i++) {
          map.put(new Integer(i), i);

          }
          System.out.println(count+" over");
          }
          };

          t1.start();
          }
          }

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-06 09:27 by bigwesthorse
          @豬兒笨笨
          對(duì)于concurrenthashmap
          用一個(gè)批處理寫(xiě)1000多個(gè)start javaw TestLock
          肯定會(huì)出現(xiàn)的,我說(shuō)了概率很低,基本上兩三百個(gè)程序會(huì)有個(gè)卡死
          你就等著那個(gè)批處理狂跑就行了,1到2分鐘之后,你就會(huì)感到cpu100%了
          被某個(gè)進(jìn)程霸占了,一直hang在那里

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-06 15:36 by 豬兒笨笨
          沒(méi)有明白樓上說(shuō)什么意思?
          這樣說(shuō)吧,是否在一個(gè)JVM內(nèi),還是說(shuō)同時(shí)啟動(dòng)多個(gè)JVM?
          如果多個(gè)JVM,就很難說(shuō)有什么問(wèn)題,比如說(shuō)用光了資源,等等。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-06 16:16 by bigwesthorse
          @豬兒笨笨
          就是這個(gè)程序是否出現(xiàn)死鎖要看rp的,跑個(gè)200多次才會(huì)出現(xiàn)一次
          我用批處理連續(xù)跑了上千次,出現(xiàn)了好幾次死鎖的情況

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?  回復(fù)  更多評(píng)論   

          2010-08-07 10:51 by 天快黑了
          感謝大家的回復(fù),這個(gè)問(wèn)題確實(shí)很難解釋清楚。我們只能注意,多線程下千萬(wàn)不要使用非線程安全的對(duì)象。

          # re: 誰(shuí)能幫忙解釋一下為什么這個(gè)程序會(huì)死鎖?[未登錄](méi)  回復(fù)  更多評(píng)論   

          2010-10-20 16:59 by littleJava
          @豬兒笨笨
          ConcurrentHashMap只是保證Happens-before關(guān)系,勉強(qiáng)的線程安全,如果需要保證數(shù)據(jù)一致性,還是用Collections.synchronizedMap(Map map)方法,利用的synchronized機(jī)制,規(guī)劃好代碼流程來(lái)實(shí)現(xiàn)線程安全

          posts - 5, comments - 25, trackbacks - 0, articles - 1

          Copyright © 天快黑了

          主站蜘蛛池模板: 大宁县| 寻乌县| 和政县| 洛南县| 正蓝旗| 潼南县| 馆陶县| 沁水县| 巴塘县| 丰县| 乾安县| 莱阳市| 讷河市| 广饶县| 阿图什市| 海晏县| 奎屯市| 中卫市| 卢湾区| 平乡县| 乃东县| 金昌市| 甘南县| 仪陇县| 东海县| 潮安县| 新丰县| 屏边| 什邡市| 棋牌| 曲水县| 左权县| 和龙市| 建德市| 昆明市| 子洲县| 吐鲁番市| 北辰区| 虎林市| 绥芬河市| 汝南县|