剛才用jstack解決了一個進程死鎖的問題——其實早就解決了,也知道原因,只是一直沒找到死鎖的位置,不太甘心而已。
流程大致如下:
(0)環境要求,JDK1.6及以上
(1)先找到進程的PID,Windows下,打開進程管理器,按照名字排序,可以找到叫做javaw.exe的進程(java虛擬機進程一律叫做javaw.exe),要找出哪個是你的進程,記住當前進程列表,然后重啟你的進程,PID刷新過的那個即是你的進程。
(2)在CMD下運行:jstack pid,jstack會在console上打出一系列信息
(3)分析上述信息
實例:
我這個問題的的jstack信息如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
C:\Documents and Settings\user>jstack 6652 2012 - 06 - 07 21 : 32 : 02 Full thread dump Java HotSpot(TM) Client VM ( 16.3 -b01 mixed mode, sharing): "Thread-1" daemon prio= 6 tid= 0x03010c00 nid= 0xcdc waiting for monitor entry [ 0x0 339f000] java.lang.Thread.State: BLOCKED (on object monitor) at org.apache.commons.net.telnet.TelnetInputStream.__read(TelnetInputStr eam.java: 122 ) - waiting to lock < 0x22942280 > (a org.apache.commons.net.ftp.FTPClient) at org.apache.commons.net.telnet.TelnetInputStream.run(TelnetInputStream .java: 535 ) at java.lang.Thread.run(Thread.java: 619 ) "Framework Event Dispatcher" daemon prio= 6 tid= 0x03010400 nid= 0x998 in Object.wa it() [ 0x0334f000 ] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x228fa800 > (a org.eclipse.osgi.framework.eventmgr.EventMa nager$EventThread) at java.lang.Object.wait(Object.java: 485 ) at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.getNextE vent(EventManager.java: 400 ) - locked < 0x228fa800 > (a org.eclipse.osgi.framework.eventmgr.EventManage r$EventThread) at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(Even tManager.java: 336 ) "Start Level Event Dispatcher" daemon prio= 6 tid= 0x02fcf400 nid= 0x2638 in Object .wait() [ 0x032de000 ] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x2295db48 > (a [I) at java.lang.Object.wait(Object.java: 485 ) at org.apache.commons.net.telnet.TelnetInputStream.read(TelnetInputStrea m.java: 339 ) - locked < 0x2295db48 > (a [I) at org.apache.commons.net.telnet.TelnetInputStream.read(TelnetInputStrea m.java: 466 ) at java.io.BufferedInputStream.read1(BufferedInputStream.java: 256 ) at java.io.BufferedInputStream.read(BufferedInputStream.java: 317 ) - locked < 0x2295fe18 > (a java.io.BufferedInputStream) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java: 264 ) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java: 306 ) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java: 158 ) - locked < 0x22961f88 > (a java.io.InputStreamReader) at java.io.InputStreamReader.read(InputStreamReader.java: 167 ) at java.io.BufferedReader.fill(BufferedReader.java: 136 ) at java.io.BufferedReader.readLine(BufferedReader.java: 299 ) - locked < 0x22961f88 > (a java.io.InputStreamReader) at java.io.BufferedReader.readLine(BufferedReader.java: 362 ) at org.apache.commons.net.ftp.FTP.__getReply(FTP.java: 264 ) at org.apache.commons.net.ftp.FTP._connectAction_(FTP.java: 335 ) at org.apache.commons.net.ftp.FTPClient._connectAction_(FTPClient.java: 5 50 ) at org.apache.commons.net.SocketClient.connect(SocketClient.java: 163 ) at com.mycompany.dc.ftp.client.FTPClientImpl.connect(FTPClientImpl.java: 7 5 ) - locked < 0x22942280 > (a org.apache.commons.net.ftp.FTPClient) at com.mycompany.dc.ftp.client.FTPClientFactoryImpl.getClient(FTPClientFa ctoryImpl.java: 35 ) - locked < 0x228f9310 > (a java.lang.Object) at ftpclienttest.Activator.start(Activator.java: 43 ) at org.eclipse.osgi.framework.internal.core.BundleContextImpl$ 1 .run(Bund leContextImpl.java: 711 ) at java.security.AccessController.doPrivileged(Native Method) at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActiv ator(BundleContextImpl.java: 702 ) at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(Bund leContextImpl.java: 683 ) at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(Bundl eHost.java: 381 ) at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(Abstra ctBundle.java: 389 ) at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Frame work.java: 1131 ) at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBund les(StartLevelManager.java: 559 ) at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBund les(StartLevelManager.java: 544 ) at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(St artLevelManager.java: 457 ) at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStart Level(StartLevelManager.java: 243 ) - locked < 0x27e68d70 > (a java.lang.Object) at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEv ent(StartLevelManager.java: 438 ) at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEv ent(StartLevelManager.java: 1 ) at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventM anager.java: 230 ) at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(Even tManager.java: 340 ) "Framework Active Thread" prio= 6 tid= 0x02ff1800 nid= 0x1fbc in Object.wait() [ 0x0 328f000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x27e65770 > (a org.eclipse.osgi.framework.internal.core.Fr amework) at org.eclipse.osgi.framework.internal.core.Framework.run(Framework.java : 1817 ) - locked < 0x27e65770 > (a org.eclipse.osgi.framework.internal.core.Framew ork) at java.lang.Thread.run(Thread.java: 619 ) "OSGi Console" prio= 6 tid= 0x03005400 nid= 0x225c waiting on condition [ 0x0323f000 ] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.eclipse.osgi.framework.internal.core.FrameworkConsole.runConsole( FrameworkConsole.java: 125 ) at org.eclipse.osgi.framework.internal.core.FrameworkConsole.run(Framewo rkConsole.java: 104 ) at java.lang.Thread.run(Thread.java: 619 ) "Low Memory Detector" daemon prio= 6 tid= 0x02c09800 nid= 0x1d68 runnable [ 0x000000 00 ] java.lang.Thread.State: RUNNABLE "CompilerThread0" daemon prio= 10 tid= 0x02c03000 nid= 0x24c4 waiting on condition [ 0x00000000 ] java.lang.Thread.State: RUNNABLE "Attach Listener" daemon prio= 10 tid= 0x02c01800 nid= 0x1138 waiting on condition [ 0x00000000 ] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" daemon prio= 10 tid= 0x02c20c00 nid= 0x18ac runnable [ 0x0000000 0 ] java.lang.Thread.State: RUNNABLE "Finalizer" daemon prio= 8 tid= 0x02bc0400 nid= 0x11ac in Object.wait() [ 0x02d8f000 ] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x27d5e5c8 > (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java: 118 ) - locked < 0x27d5e5c8 > (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java: 134 ) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java: 159 ) "Reference Handler" daemon prio= 10 tid= 0x02bbb800 nid= 0x9cc in Object.wait() [0x 02d3f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x27d5e650 > (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java: 485 ) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java: 116 ) - locked < 0x27d5e650 > (a java.lang.ref.Reference$Lock) "main" prio= 6 tid= 0x008a6c00 nid= 0x22ec in Object.wait() [ 0x0098f000 ] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on < 0x22c303c8 > (a org.eclipse.core.runtime.internal.adaptor.S emaphore) at org.eclipse.core.runtime.internal.adaptor.Semaphore.acquire(Semaphore .java: 55 ) - locked < 0x22c303c8 > (a org.eclipse.core.runtime.internal.adaptor.Semap hore) at org.eclipse.core.runtime.adaptor.EclipseStarter.updateSplash(EclipseS tarter.java: 1251 ) at org.eclipse.core.runtime.adaptor.EclipseStarter.setStartLevel(Eclipse Starter.java: 1213 ) at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarte r.java: 288 ) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.ja va: 175 ) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl. java: 39 ) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java: 25 ) at java.lang.reflect.Method.invoke(Method.java: 597 ) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java: 622 ) at org.eclipse.equinox.launcher.Main.basicRun(Main.java: 577 ) at org.eclipse.equinox.launcher.Main.run(Main.java: 1410 ) at org.eclipse.equinox.launcher.Main.main(Main.java: 1386 ) "VM Thread" prio= 10 tid= 0x02bba000 nid= 0xdb4 runnable "VM Periodic Task Thread" prio= 10 tid= 0x02c0e400 nid= 0x24ac waiting on condition JNI global references: 677 |
分析:
根據提示,有兩個線程都用到了ftpClient這個對象作為鎖,而且前一個得到鎖的要等待后一個需要這個鎖的返回結果,造成死鎖。這兩處分別為:
(1) at org.apache.commons.net.telnet.TelnetInputStream.__read(TelnetInputStr
eam.java:122)
(2) - locked <0x22942280> (a org.apache.commons.net.ftp.FTPClient)
at com.sagemcom.dc.ftp.client.FTPClientFactoryImpl.getClient(FTPClientFa
ctoryImpl.java:35)
- locked <0x228f9310> (a java.lang.Object)
前者是系統自己用的鎖,后者是我代碼里面加的。自己代碼里面換一個對象做鎖就解決了。
總結
jstack在解決問題上還是比較有幫助的,信息簡潔有效,其實有很多圖形化的分析工具是基于它的。但jstack需要jdk1.6以上的版本才支持。
以上就是本文關于通過jstack分析解決進程死鎖問題實例代碼的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!
原文鏈接:http://blog.sina.com.cn/s/blog_855eab95010157uv.html