我有一个 Actor ,它接收消息,并通过httpclient下载文件。
代码示例:
@Override
public void onReceive(Object message) throws Exception {
HttpClient client = new DefaultHttpClient();
...
httpGet.releaseConnection()
...
}
几天后出现问题。
从日志中,它显示了 httpclient 请求时的 actor block 。
阻止是可以的,但似乎 httpclient 死锁,actor 不进一步处理任何消息。
这是怎么发生的?
日志:
Sending message to DownloadActor
...DownloadActor Receive message
BasicClientConnectionManager:159 - Get connection for route
...
BasicClientConnectionManager:201 - Releasing connection
Sending message to DownloadActor
...DownloadActor Receive message
BasicClientConnectionManager:159 - Get connection for route
Sending message to DownloadActor
Sending message to DownloadActor
Sending message to DownloadActor
Sending message to DownloadActor
Sending message to DownloadActor
线程转储:
"grabSystem-akka.actor.default-dispatcher-67" prio=10 tid=0x00007fa4d4004800 nid=0x2ad8 waiting on condition [0x00007fa5671a7000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x0000000411a2a010> (a akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinPool)
at scala.concurrent.forkjoin.ForkJoinPool.scan(ForkJoinPool.java:2075)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
"grabSystem-akka.actor.default-dispatcher-66" prio=10 tid=0x00007fa4b4001000 nid=0x5ea runnable [0x00007fa5679ae000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.apache.http.impl.io.AbstractSessionInputBuffer.read(AbstractSessionInputBuffer.java:204)
at org.apache.http.impl.conn.LoggingSessionInputBuffer.read(LoggingSessionInputBuffer.java:82)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:177)
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:138)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
- locked <0x0000000412038e10> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.Reader.read(Reader.java:140)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:233)
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:273)
at com.baidu.grab.core.DownloadActor.onReceive(DownloadActor.java:102)
at akka.actor.UntypedActor$$anonfun$receive$1.applyOrElse(UntypedActor.scala:167)
at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
at akka.actor.UntypedActor.aroundReceive(UntypedActor.scala:97)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
at akka.actor.ActorCell.invoke(ActorCell.scala:487)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
at akka.dispatch.Mailbox.run(Mailbox.scala:220)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
最佳答案
如果我理解你的问题,这可能有助于解释发生了什么。参与者连续处理来自其邮箱的消息。如果 HttpClient 正在阻塞,那么参与者将无法完成该消息的处理,并且不会处理进一步的消息,直到清除该阻塞并且可以完成消息处理。
如果您想让 Actor 不阻塞,请在将来包装 HttpClient Activity 的调用,或者将工作发送到 Actor 池以在您继续处理时处理这种情况。
关于java - Akka Actor 中的 Httpclient 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27373703/