2012-02-08 124 views
1

是下面的方法可能導致線程掛起,從而導致其他線程掛起,最終建立一個堆棧和崩潰的應用程序服務器?線程掛起導致其他線程掛起

private static Hashtable content = new Hashtable(); 
private static int cleanout; 

private static void cleanoutCache() { 

    if(cleanout > 50000) { 

     synchronized(PollCacheManager.class) { 

      Enumeration emu = content.keys(); 

      while(emu.hasMoreElements()) { 

       String key = (String)emu.nextElement(); 

       PollCacheStore bean = (PollCacheStore)content.get(key); 

       if((System.currentTimeMillis() - bean.getLastInitialized()) > 86400000) { 

        content.remove(key); 

       } 

      } 

      // reset cleanout 
      cleanout = 0; 

     } 

    } 

} 

感謝您的幫助


我粘貼運行我的測試案例模擬我在my previous question前面提到的問題時產生的線程轉儲的快照。

所有「Servlet.Engine.Transports」線程都與我的應用程序有關。看起來他們都在監視器上等着。但沒有提供關於他們在等待什麼資源的更多細節。我在分析這些線程轉儲時有點新鮮。看起來不是僵局,不是競爭狀態,也不是資源爭奪。但是,在我的負載測試工具的結果中,過程懸掛是顯而易見的。感謝您的幫助

全部線程轉儲:

"Thread-1727" prio=5 tid=0x2aea620 nid=0x9a2 waiting on monitor [0xb6481000..0xb6481a00] 
    at java.lang.Thread.sleep(Native Method) 
    at com.ibm.websphere.personalization.util.timer.PznTimerEvents.run(PznTimerEvents.java:222) 
    at java.lang.Thread.run(Thread.java:479) 

"Thread-1683" daemon prio=5 tid=0x1a21668 nid=0x973 runnable [0xb4581000..0xb4581a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:181) 
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:220) 
    at java.io.BufferedInputStream.read(BufferedInputStream.java:275) 
    at com.sun.jndi.ldap.Connection.run(Connection.java:581) 
    at java.lang.Thread.run(Thread.java:479) 

"Thread-1682" daemon prio=5 tid=0x4ed830 nid=0x972 runnable [0xb5301000..0xb5301a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:181) 
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:220) 
    at java.io.BufferedInputStream.read(BufferedInputStream.java:275) 
    at com.sun.jndi.ldap.Connection.run(Connection.java:581) 
    at java.lang.Thread.run(Thread.java:479) 

"Thread-1681" daemon prio=5 tid=0x1ec1a20 nid=0x971 runnable [0xb5401000..0xb5401a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:181) 
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:220) 
    at java.io.BufferedInputStream.read(BufferedInputStream.java:275) 
    at com.sun.jndi.ldap.Connection.run(Connection.java:581) 
    at java.lang.Thread.run(Thread.java:479) 

"Servlet.Engine.Transports : 387" daemon prio=5 tid=0x15386f8 nid=0x943 waiting on monitor [0xb4781000..0xb4781a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 385" daemon prio=5 tid=0x51e898 nid=0x93e waiting on monitor [0xb3281000..0xb3281a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 384" daemon prio=5 tid=0x464760 nid=0x93d waiting on monitor [0xb3381000..0xb3381a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 382" daemon prio=5 tid=0x1141de8 nid=0x8a0 waiting on monitor [0xb3581000..0xb3581a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 380" daemon prio=5 tid=0x1151ad8 nid=0x6b5 waiting on monitor [0xb3e81000..0xb3e81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 366" daemon prio=5 tid=0x1a1d110 nid=0x3fb waiting on monitor [0xb4b81000..0xb4b81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 365" daemon prio=5 tid=0x4e8bd8 nid=0x3fa waiting on monitor [0xb6281000..0xb6281a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 362" daemon prio=5 tid=0x17055b0 nid=0x3f7 waiting on monitor [0xb3481000..0xb3481a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 356" daemon prio=5 tid=0x1ddbae0 nid=0x3f1 waiting on monitor [0xb9c01000..0xb9c01a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Servlet.Engine.Transports : 299" daemon prio=5 tid=0x2519028 nid=0x3b5 waiting on monitor [0xb6001000..0xb6001a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"SoapConnectorThreadPool : 3" daemon prio=5 tid=0x15d49f0 nid=0x1ae waiting on monitor [0xb2e81000..0xb2e81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Alarm : 3" daemon prio=5 tid=0x1d24c48 nid=0xa5 waiting on monitor [0xb6381000..0xb6381a00] 
    at java.lang.Object.wait(Native Method) 
    at com.ibm.ws.util.BoundedBuffer.poll(BoundedBuffer.java:192) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"Keep-Alive-Timer:" daemon prio=8 tid=0x1ec9a38 nid=0x99 waiting on monitor [0xb3f81000..0xb3f81a00] 
    at java.lang.Thread.sleep(Native Method) 
    at sun.net.www.http.KeepAliveCache.run(KeepAliveCache.java:130) 
    at java.lang.Thread.run(Thread.java:479) 

"Thread-64" daemon prio=5 tid=0x4ee700 nid=0x98 waiting on monitor [0xb4081000..0xb4081a00] 
    at java.lang.Thread.sleep(Native Method) 
    at com.ibm.ejs.j2c.poolmanager.TaskTimer.run(TaskTimer.java:119) 

"RT=7:P=908030:O=0:WSTCPTransportConnection[addr=10.24.189.74,port=47148,local=9812]" daemon prio=5 tid=0x4c73f8 nid=0x97 runnable [0xb4181000..0xb4181a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at com.ibm.rmi.iiop.Connection.readMoreData(Connection.java:909) 
    at com.ibm.rmi.iiop.Connection.createInputStream(Connection.java:742) 
    at com.ibm.rmi.iiop.Connection.doReaderWorkOnce(Connection.java:2447) 
    at com.ibm.rmi.transport.ReaderThread.run(ReaderPoolImpl.java:138) 

"RT=6:P=908030:O=0:WSTCPTransportConnection[addr=10.24.189.74,port=9812,local=47148]" daemon prio=5 tid=0x3b7860 nid=0x96 runnable [0xb4281000..0xb4281a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at com.ibm.rmi.iiop.Connection.readMoreData(Connection.java:909) 
    at com.ibm.rmi.iiop.Connection.createInputStream(Connection.java:742) 
    at com.ibm.rmi.iiop.Connection.doReaderWorkOnce(Connection.java:2447) 
    at com.ibm.rmi.transport.ReaderThread.run(ReaderPoolImpl.java:138) 

"Thread-63" daemon prio=5 tid=0x1666990 nid=0x91 waiting on monitor [0xb4681000..0xb4681a00] 
    at java.lang.Thread.sleep(Native Method) 
    at com.ibm.ws.management.RoutingTable$PingThread.run(RoutingTable.java:1025) 

"ProcessDiscovery : 0" daemon prio=5 tid=0x1c7b4c8 nid=0x8b waiting on monitor [0xb4881000..0xb4881a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"SoapConnectorThreadPool : 2" daemon prio=5 tid=0x1b82798 nid=0x8a waiting on monitor [0xb4981000..0xb4981a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"SoapConnectorThreadPool : 1" daemon prio=5 tid=0x1505188 nid=0x89 waiting on monitor [0xb4a81000..0xb4a81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"ORB.thread.pool : 1" daemon prio=5 tid=0x24cfd20 nid=0x83 waiting on monitor [0xb4c81000..0xb4c81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"ORB.thread.pool : 0" daemon prio=5 tid=0x15025c0 nid=0x82 waiting on monitor [0xb4d81000..0xb4d81a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.ws.util.BoundedBuffer.take(BoundedBuffer.java:161) 
    at com.ibm.ws.util.ThreadPool.getTask(ThreadPool.java:422) 
    at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:669) 

"RT=5:P=908030:O=0:WSSSLTransportConnection[addr=10.25.168.38,port=33762,local=46854]" daemon prio=5 tid=0x1520f20 nid=0x81 runnable [0xb4e81000..0xb4e81a00] 
    at java.net.SocketInputStream.socketRead(Native Method) 
    at java.net.SocketInputStream.read(SocketInputStream.java:85) 
    at com.ibm.sslite.t.a(Unknown Source) 
    at com.ibm.sslite.t.b(Unknown Source) 
    at com.ibm.sslite.t.a(Unknown Source) 
    at com.ibm.sslite.a.read(Unknown Source) 
    at com.ibm.jsse.a.read(Unknown Source) 
    at com.ibm.rmi.iiop.Connection.readMoreData(Connection.java:909) 
    at com.ibm.rmi.iiop.Connection.createInputStream(Connection.java:742) 
    at com.ibm.rmi.iiop.Connection.doReaderWorkOnce(Connection.java:2447) 
    at com.ibm.rmi.transport.ReaderThread.run(ReaderPoolImpl.java:138) 

"Thread-53" prio=5 tid=0x29558 nid=0x1 waiting on monitor [0..0xffbedb10] 

"[email protected]" prio=5 tid=0x17dacf8 nid=0x80 runnable [0xb4f81000..0xb4f81a00] 
    at java.net.PlainDatagramSocketImpl.receive(Native Method) 
    at java.net.DatagramSocket.receive(DatagramSocket.java:387) 
    at com.ibm.ws.management.discovery.transport.MulticastServer.run(MulticastServer.java:196) 
    at java.lang.Thread.run(Thread.java:479) 

"ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9044]" prio=5 tid=0x157f330 nid=0x7f runnable [0xb5981000..0xb5981a00] 
    at java.net.PlainSocketImpl.socketAccept(Native Method) 
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:463) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:238) 
    at java.net.ServerSocket.accept(ServerSocket.java:217) 
    at com.ibm.jsse.bg.accept(Unknown Source) 
    at com.ibm.ws.http.HttpTransport.run(HttpTransport.java:235) 
    at java.lang.Thread.run(Thread.java:479) 

"ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9091]" prio=5 tid=0x15d10c0 nid=0x7e runnable [0xb5a81000..0xb5a81a00] 
    at java.net.PlainSocketImpl.socketAccept(Native Method) 
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:463) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:238) 
    at java.net.ServerSocket.accept(ServerSocket.java:217) 
    at com.ibm.ws.http.HttpTransport.run(HttpTransport.java:235) 
    at java.lang.Thread.run(Thread.java:479) 

"ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9444]" prio=5 tid=0x1693c28 nid=0x7d runnable [0xb5b81000..0xb5b81a00] 
    at java.net.PlainSocketImpl.socketAccept(Native Method) 
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:463) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:238) 
    at java.net.ServerSocket.accept(ServerSocket.java:217) 
    at com.ibm.jsse.bg.accept(Unknown Source) 
    at com.ibm.ws.http.HttpTransport.run(HttpTransport.java:235) 
    at java.lang.Thread.run(Thread.java:479) 

"ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=9081]" prio=5 tid=0x24d2f78 nid=0x7c runnable [0xb5e01000..0xb5e01a00] 
    at java.net.PlainSocketImpl.socketAccept(Native Method) 
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:463) 
    at java.net.ServerSocket.implAccept(ServerSocket.java:238) 
    at java.net.ServerSocket.accept(ServerSocket.java:217) 
    at com.ibm.ws.http.HttpTransport.run(HttpTransport.java:235) 
    at java.lang.Thread.run(Thread.java:479) 

"Dispatcher-Thread-52" daemon prio=1 tid=0x509da0 nid=0x7b waiting on monitor [0xb5f01000..0xb5f01a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at org.apache.log4j.Dispatcher.run(AsyncAppender.java:293) 

"Thread-51" prio=5 tid=0x254138 nid=0x7a waiting on monitor [0xb5c81000..0xb5c81a00] 
    at java.lang.Thread.sleep(Native Method) 
    at com.ibm.wcm.jobs.Scheduler.run(Scheduler.java:68) 
    at java.lang.Thread.run(Thread.java:479) 

"wcp_1328597020006" prio=5 tid=0x2a5c628 nid=0x76 waiting on monitor [0xb6101000..0xb6101a00] 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:415) 
    at com.ibm.wcp.analysis.util.MultiAccessQueue.dequeue(MultiAccessQueue.java:223) 
    at com.ibm.wcp.analysis.event.ListenerThread.run(ListenerThread.java:87) 

.....更多(因爲這裏字符)

+0

簡答題:沒有。較長的回答:這段代碼有很多問題。我建議您使用EhCache等預先構建(並經過充分測試)的緩存。 – kdgregory 2012-02-09 01:33:52

+0

@ user1096804不知道WebSphere Threadpool的細節我會說「Servlet.Engine.Transports」線程正在等待傳入的工作。 – afrischke 2012-02-09 08:41:35

回答

1

您應該在同步塊內移動「清除大於50000」測試,以確保所有線程都能看到其值最新版本,並在方法結束時對其進行修改。

如果對「content」和「cleanout」變量的所有其他訪問都受到「PollCacheManager.class」監視器(包含讀取)的保護,則其餘部分看起來不錯。

+0

非常感謝您的即時更新。你能否再解釋一下,這樣的安排會導致這個問題。我有類似的想法,認爲「清理超過50000」可能是原因,但我無法自己證明這一點,我猜這是由於我對Synchronized塊的工作原理缺乏瞭解。感謝您的幫助 – dale 2012-02-09 00:00:32

+0

線程之間共享的每個數據必須以某種方式同步(同步關鍵字,或與來自java.util.concurrent的鎖定或使用線程安全結構)。在這裏,您的「清除」屬性在沒有任何同步的情況下被讀取(在測試中)。這可能會導致線程無法更新值(在方法結束時設置爲0)。而且,我看到它的價值並沒有在這種方法中增加,所以我猜它是在其他地方。請確保它在同步塊中完成,使用與上述代碼中相同的監視器。 – 2012-02-09 00:46:16

+0

如果您想要了解所有這些同步工作的最佳解釋,請參閱SCJP考試準備手冊(在亞馬遜上搜索「SCJP 6」)。你會發現這本書在學習Java時非常有價值。 – 2012-02-09 00:48:28

0

我會使整個功能同步,給你使用這種同步,我想知道你爲什麼使用Hashtable(它也是同步的)?

您是否有可能遇到一些競爭條件,因爲其他訪問此散列表不受同一個鎖保護?

+0

感謝Nim,這種情況是否會導致在同步塊內給定哈希表操作的掛起?這可能導致死鎖嗎?在這種情況下,哈希表如何使用卡住的線程?謝謝 – dale 2012-02-09 01:01:01

+0

@ user1096804,不確定,只是假設,我會做線程轉儲,看看他們都卡住了。這是最快的方法。 – Nim 2012-02-09 01:03:22

1

雖然問題中提供的代碼可能代表瓶頸(在靜態字段/類對象上同步),但只要我們可以假定正在執行的線程將會能夠在合理的時間內遍歷Hashtable中的鍵。然而

注意,它是有點危險的PollCacheManager類對象當且僅當PollCacheManager上同步公開訪問外部代碼可能獲得PollCacheManager類對象上的鎖,因此indefinitively延遲執行的線程(見this page瞭解詳細信息) 。

如果遇到應用程序掛起,最好的選擇是觸發線程轉儲(只需向JVM發送一個SIGQUIT(在Unix上kill -3),在Windows上按Ctrl-Break)並分析堆棧跟蹤。