问题描述
我们在我们的网络应用中实现了一项功能,通过使用Play的延续来更新GUI,以响应服务器中的新事件,就像聊天应用一样。在生产中运行一段时间后,我们开始体验服务器挂起,更具体地说,我们的Glassfish服务器的http连接器停止接受新的请求。线程转储告诉我们,来自http线程池的所有http线程都在等待Play Promises被调用。我们的线程池有5个线程(默认编号),这意味着有5个客户端等待被通知,服务器不能接受更多的http连接,除非一些实际的客户端关闭它的连接。
根据Play关于继续/请求暂停的文档,当通过调用
await()
来暂停请求时,请求的线程应该被释放。这不是在这里发生的事情。 参考:
我对Play的源代码做了一些研究,但找不到任何提示。另外我的代码似乎没问题,但我不确定(见下文)。我希望有人可能会指出我可能做错了什么。
版本:
Play 1.2.3
Glassfish 3.1.1
源代码:
public class Sessions extends Controller {
public static void waitFor(Query query,long lastSessionId,List< Long> openSessionIds){
String clientId = request.remoteAddress;
列表< Session> sessions = query
.with(new UpdatedSessions(lastSessionId,openSessionIds))
.execute();
Logger.info(%s - >自%s +%s:%s以来更新的会话,clientId,lastSessionId,openSessionIds,会话);
while(sessions.isEmpty()){
List< Long> ids = await(MailBox.watch(query,clientId));
Logger.info(%s - >收到的ids:%s,clientId,ids);
sessions = query.with(new SessionIds(ids))。execute();
Logger.info(%s - >查询的会话:%s,clientId,会话);
Logger.info(%s - >交付%s,clientId,会话);
列表< Tile> tiles = Tile.forGates(query.gates());
渲染(会话,图块);
}
}
public class MailBox {
private static List< Promise< List< Long>>> promises = Collections.synchronizedList(new ArrayList< Promise< List< Long>>>());
public static Future< List< Long>> (Query query,String clientId){
Logger.info(Mailbox.watch(%s,%s),query,clientId);
Promise< List< Long>> promise = new Promise< List< Long>>();
promises.add(promise);
返回承诺;
$ b $ public static void put(final long sessionId){
Logger.info(Mailbox.put(%s):promises =%s,sessionId,promises) ;
if(promises.isEmpty())
return;
final List< Promise< List< Long>>> targets = seizePromises();
new线程(){
@Override
public void run(){
//这是一个列表,因为我们会在通知等待的客户端之前累积IDs
List< Long> ids = Arrays.asList(sessionId);
Logger.info(Mailbox.put(%s):target =%s,sessionId,targets); (Promise< List< Long>> promise:targets)
promise.invoke(ids);
}
} .start();
}
private static List< Promise< List< Long>>> seizePromises(){
List< Promise< List< Long>>> result = new ArrayList< Promise< List< Long>>>();
synchronized(promises){
result.addAll(promises);
promises.clear();
}
返回结果;
$ b线程转储(修剪完成, http://bastebin.com/1TdV1njv ): b
完全线程转储OpenJDK 64位服务器虚拟机(20.0-b11混合模式):
RMI TCP连接(空闲) daemon prio = 10 tid = 0x0000000000ffe000 nid = 0xca0等待条件[0x00007f5cf1fa4000]
java.lang.Thread.State:TIMED_WAITING(停放)
at sun.misc.Unsafe.park(Native Method)
- 停车等待< 0x00000000e27f9300> (java.util.concurrent.SynchronousQueue $ TransferStack)$ java.util.concurrent.locks.LockSupport.parkNanos上的b $ b(LockSupport.java:226)$ java.util.concurrent.SynchronousQueue上的
$ TransferStack。在java.util.concurrent.SynchronousQueue上
$ TransferStack.transfer(SynchronousQueue.java:352)$ java.util.concurrent.SynchronousQueue.poll上的
(SynchronousQueue.java: 903)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java .util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:603)
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- None
Object.wait()[0x00007f5cebefd000]
java.lang.Thread.State: TIMED_WAITING(在对象mo上(原始方法)
- 等待< 0x00000000fe5242d8> (a [I]
at com.sun.jmx.remote.internal.ServerCommunicatorAdmin $ Timeout.run(ServerCommunicatorAdmin.java:168)
- locked< 0x00000000fe5242d8> (a [I]
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- None
RMI TCP连接(3)-127.0.0.1守护进程prio = 10 tid = 0x0000000001374000 nid = 0xc9c runnable [0x00007f5cf20a5000]
java.lang.Thread.State:RUNNABLE
at java.net.SocketInputStream。在java.net.SocketInputStream.read(SocketInputStream.java:146)
在java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
。 io.BufferedInputStream.read(BufferedInputStream.java:254)
- 锁定< 0x00000000fe5a2010> (一个java.io.BufferedInputStream)
在java.io.FilterInputStream.read(FilterInputStream.java:83)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport $ ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:603)
at java .lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- < 0x00000000fe521bc8> (a java.util.concurrent.ThreadPoolExecutor $ Worker)
RMI TCP Accept-0守护进程prio = 10 tid = 0x0000000001375000 nid = 0xc99 runnable [0x00007f5ceb3f2000]
java.lang.Thread .State:在java.net.PlainSocketImpl.socketAccept(Native方法)上运行
在java.net.AbstractPlainSocketImpl.accept处
(AbstractPlainSocketImpl.java:375)在java.net.ServerSocket处
。 implAccept(ServerSocket.java:470)
at java.net.ServerSocket.accept(ServerSocket.java:438)
at sun.management.jmxremote.LocalRMIServerSocketFactory $ 1.accept(LocalRMIServerSocketFactory.java:52)
。在sun.rmi.transport.tcp.TCPTransport $ AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
在sun.rmi.transport.tcp.TCPTransport $ AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:679)
锁定的可用同步器:
- None
附加侦听器守护程序prio = 10 tid = 0x0000000001341800 nid = 0xc98等待条件[0x00000000000 00000]
java.lang.Thread.State:RUNNABLE
锁定的拥有同步器:
- None
http-thread-pool-8080( 5)daemon prio = 10 tid = 0x00007f5cec119800 nid = 0xbb5等待条件[0x00007f5cea8e6000]
java.lang.Thread.State:WAITING(停放)
at sun.misc.Unsafe.park(Native Method )
- 停车等待< 0x00000000fe4d6bb8> (java.util.concurrent.CountDownLatch $ Sync)
在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
在java.util.concurrent.locks.AbstractQueuedSynchronizer。在抽象类中抽象类抽象化(AbstractQueuedSynchronizer.java:838)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer。 java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F $ Promise.get(F.java:46)
play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java :847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(Standard WrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)$ b在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
。在组织.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise .v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly .http.ProcessorTask.doProcess(临cessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 225)
)
在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:679)
锁定拥有同步器:
- < 0x00000000e39f4eb0> (a java.util.concurrent.locks.ReentrantLock $ NonfairSync)
http-thread-pool-8080(4)daemon prio = 10 tid = 0x00007f5cec142800 nid = 0xbb4等待条件[0x00007f5cea9e7000]
java.lang.Thread.State:WAITING(停放)
at sun.misc.Unsafe.park(本地方法)
- 停车等待< 0x00000000f6ff9e90> (java.util.concurrent.CountDownLatch $ Sync)
在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
在java.util.concurrent.locks.AbstractQueuedSynchronizer。在抽象类中抽象类抽象化(AbstractQueuedSynchronizer.java:838)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer。 java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F $ Promise.get(F.java:46)
play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java :847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(Standard WrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)$ b在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
。在组织.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise .v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly .http.ProcessorTask.doProcess(临cessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 225)
)
在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- < 0x00000000fe4a3b90> (a java.util.concurrent.locks.ReentrantLock $ NonfairSync)
http-thread-pool-8080(3)daemon prio = 10 tid = 0x00007f5cec140800 nid = 0xbb3等待条件[0x00007f5ceaae8000]
java.lang.Thread.State:WAITING(驻留)
at sun.misc.Unsafe.park(本地方法)
- 驻留等待< 0x00000000fe4a3288> (java.util.concurrent.CountDownLatch $ Sync)
在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
在java.util.concurrent.locks.AbstractQueuedSynchronizer。在抽象类中抽象类抽象化(AbstractQueuedSynchronizer.java:838)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer。 java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F $ Promise.get(F.java:46)
play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java :847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(Standard WrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)$ b在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
。在组织.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise .v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly .http.ProcessorTask.doProcess(临cessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 225)
)
在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- < 0x00000000e28c0fd0> (a java.util.concurrent.locks.ReentrantLock $ NonfairSync)
http-thread-pool-8080(2)daemon prio = 10 tid = 0x00007f5cec02d000 nid = 0xbb2等待条件[0x00007f5ceabe9000]
java.lang.Thread.State:WAITING(停车)
at sun.misc.Unsafe.park(本地方法)
- 停车等待< 0x00000000f72411d8> (java.util.concurrent.CountDownLatch $ Sync)
在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
在java.util.concurrent.locks.AbstractQueuedSynchronizer。在抽象类中抽象类抽象化(AbstractQueuedSynchronizer.java:838)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer。 java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F $ Promise.get(F.java:46)
play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java :847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(Standard WrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)$ b在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
。在组织.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise .v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly .http.ProcessorTask.doProcess(临cessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 225)
)
在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- < 0x00000000f63b3958> (a java.util.concurrent.locks.ReentrantLock $ NonfairSync)
http-thread-pool-8080(1)daemon prio = 10 tid = 0x00007f5cec02c800 nid = 0xbb1等待条件[0x00007f5ceb0ee000]
java.lang.Thread.State:WAITING(停放)
at sun.misc.Unsafe.park(本地方法)
- 停车等待< 0x00000000f7424bd0> (java.util.concurrent.CountDownLatch $ Sync)
在java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
在java.util.concurrent.locks.AbstractQueuedSynchronizer。在抽象类中抽象类抽象化(AbstractQueuedSynchronizer.java:838)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
在java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer。 java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F $ Promise.get(F.java:46)
play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java :847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(Standard WrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)$ b在com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
。在组织.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise .v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly .http.ProcessorTask.doProcess(临cessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:在com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137 225)
)
在com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
。在COM .sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask .doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71 )
at com.sun.grizzly.util.AbstractThreadPool $ Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool $ Worker.run(AbstractThreadPool.java:513 )
在java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- < 0x00000000f63c78b0> (一个java.util.concurrent.locks.ReentrantLock $ NonfairSync)
SCR Component Actor守护进程prio = 10 tid = 0x00007f5ce472d000 nid = 0xba8在Object.wait()[0x00007f5ceadec000]
java.lang.Thread.State:WAITING(在对象监视器上)
在java.lang.Object.wait(本地方法)
- 等待< 0x00000000e260c920> (java.util.LinkedList)
在java.lang.Object.wait(Object.java:502)
在org.apache.felix.scr.impl.ComponentActorThread.run(ComponentActorThread.java: 74)
- 锁定< 0x00000000e260c920> (a java.util.LinkedList)
在java.lang.Thread.run(Thread.java:679)
锁定的可用同步器:
- None
pool-7-thread-1prio = 10 tid = 0x00007f5ce5134800 nid = 0xba7等待条件[0x00007f5ceaceb000]
java.lang.Thread.State:WAITING(停放)
在太阳下。 misc.Unsafe.park(本地方法)
- 停车等待< 0x00000000e260cb78> (java.util.concurrent.locks.AbstractQueuedSynchronizer $ ConditionObject)$ java.util.concurrent.locks.LockSupport.park处的
(LockSupport.java:186)$ java.util.concurrent.locks处的
。的AbstractQueuedSynchronizer $ ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
在java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:386)
在java.util.concurrent.ThreadPoolExecutor.getTask(的ThreadPoolExecutor。 java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
锁定的拥有同步器:
- None
$ p正如Guillaume在Google网站上提到的那样,这是因为Play continuations只能在内置的Netty服务器上运行。你完全正确的是,这些信息在文档中是缺乏的,但仅仅是使用Netty的Play可以控制请求线程。对于所有其他服务器,Play需要创建一个围绕servlet API的包装,这意味着一个线程不能被Play所持有。
不幸的是,这是一个交易当使用Play部署到除首选平台之外的任何其他功能。
We have implemented a feature in our web app that updates the GUI in response to new events in the server by using Play's continuations, just like a chat app. After running it for some time in production we started to experience server hangs, more specifically the http connector of our Glassfish server stopped accepting new requests. A thread dump shows us that all http threads from the http thread pool are waiting for Play Promises to be invoked. Our thread pool has 5 threads (the default number) which means there are 5 clients waiting to be notified and the server cannot accept more http connections unless some of the actual clients closes its connection.
According Play's docs on continuations/request suspension when a request is suspended by calling await()
the request's thread should be freed. That's not what is happening here.
Reference: http://www.playframework.org/documentation/1.2.3/asynchronous
I did some research on Play's source code and could not find any hint. Also my code seems to be all right, but I'm not sure (see below). I hope that somebody may point me out to what I might be doing wrong.
Versions:
Play 1.2.3
Glassfish 3.1.1
Source code:
public class Sessions extends Controller {
public static void waitFor(Query query, long lastSessionId, List<Long> openSessionIds) {
String clientId = request.remoteAddress;
List<Session> sessions = query
.with(new UpdatedSessions(lastSessionId, openSessionIds))
.execute();
Logger.info("%s -> Updated sessions since %s + %s: %s", clientId, lastSessionId, openSessionIds, sessions);
while(sessions.isEmpty()) {
List<Long> ids = await(MailBox.watch(query, clientId));
Logger.info("%s -> Received ids: %s", clientId, ids);
sessions = query.with(new SessionIds(ids)).execute();
Logger.info("%s -> Queried sessions: %s", clientId, sessions);
}
Logger.info("%s -> Delivering %s", clientId, sessions);
List<Tile> tiles = Tile.forGates(query.gates());
render(sessions, tiles);
}
}
public class MailBox {
private static List<Promise<List<Long>>> promises = Collections.synchronizedList(new ArrayList<Promise<List<Long>>>());
public static Future<List<Long>> watch(Query query, String clientId) {
Logger.info("Mailbox.watch(%s, %s)", query, clientId);
Promise<List<Long>> promise = new Promise<List<Long>>();
promises.add(promise);
return promise;
}
public static void put(final long sessionId) {
Logger.info("Mailbox.put(%s): promises=%s", sessionId, promises);
if(promises.isEmpty())
return;
final List<Promise<List<Long>>> targets = seizePromises();
new Thread() {
@Override
public void run() {
// It's a list because we will accumulate ids before notifying the waiting clients
List<Long> ids = Arrays.asList(sessionId);
Logger.info("Mailbox.put(%s): target=%s", sessionId, targets);
for(Promise<List<Long>> promise : targets)
promise.invoke(ids);
}
}.start();
}
private static List<Promise<List<Long>>> seizePromises() {
List<Promise<List<Long>>> result = new ArrayList<Promise<List<Long>>>();
synchronized (promises) {
result.addAll(promises);
promises.clear();
}
return result;
}
}
Thread dump (trimmed, see the full dump here http://pastebin.com/1TdV1njv):
2011-11-22 10:42:00
Full thread dump OpenJDK 64-Bit Server VM (20.0-b11 mixed mode):
"RMI TCP Connection(idle)" daemon prio=10 tid=0x0000000000ffe000 nid=0xca0 waiting on condition [0x00007f5cf1fa4000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000e27f9300> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:453)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:352)
at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:903)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- None
"JMX server connection timeout 87" daemon prio=10 tid=0x00000000012d6000 nid=0xc9e in Object.wait() [0x00007f5cebefd000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000fe5242d8> (a [I)
at com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:168)
- locked <0x00000000fe5242d8> (a [I)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- None
"RMI TCP Connection(3)-127.0.0.1" daemon prio=10 tid=0x0000000001374000 nid=0xc9c runnable [0x00007f5cf20a5000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:146)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read(BufferedInputStream.java:254)
- locked <0x00000000fe5a2010> (a java.io.BufferedInputStream)
at java.io.FilterInputStream.read(FilterInputStream.java:83)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000fe521bc8> (a java.util.concurrent.ThreadPoolExecutor$Worker)
"RMI TCP Accept-0" daemon prio=10 tid=0x0000000001375000 nid=0xc99 runnable [0x00007f5ceb3f2000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:375)
at java.net.ServerSocket.implAccept(ServerSocket.java:470)
at java.net.ServerSocket.accept(ServerSocket.java:438)
at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:387)
at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:359)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- None
"Attach Listener" daemon prio=10 tid=0x0000000001341800 nid=0xc98 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"http-thread-pool-8080(5)" daemon prio=10 tid=0x00007f5cec119800 nid=0xbb5 waiting on condition [0x00007f5cea8e6000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fe4d6bb8> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F$Promise.get(F.java:46)
at play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000e39f4eb0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"http-thread-pool-8080(4)" daemon prio=10 tid=0x00007f5cec142800 nid=0xbb4 waiting on condition [0x00007f5cea9e7000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f6ff9e90> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F$Promise.get(F.java:46)
at play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000fe4a3b90> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"http-thread-pool-8080(3)" daemon prio=10 tid=0x00007f5cec140800 nid=0xbb3 waiting on condition [0x00007f5ceaae8000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000fe4a3288> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F$Promise.get(F.java:46)
at play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000e28c0fd0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"http-thread-pool-8080(2)" daemon prio=10 tid=0x00007f5cec02d000 nid=0xbb2 waiting on condition [0x00007f5ceabe9000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f72411d8> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F$Promise.get(F.java:46)
at play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000f63b3958> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"http-thread-pool-8080(1)" daemon prio=10 tid=0x00007f5cec02c800 nid=0xbb1 waiting on condition [0x00007f5ceb0ee000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f7424bd0> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:838)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:998)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:235)
at play.libs.F$Promise.get(F.java:46)
at play.Invoker.invokeInThread(Invoker.java:73)
at play.server.ServletWrapper.service(ServletWrapper.java:130)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- <0x00000000f63c78b0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
"SCR Component Actor" daemon prio=10 tid=0x00007f5ce472d000 nid=0xba8 in Object.wait() [0x00007f5ceadec000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000e260c920> (a java.util.LinkedList)
at java.lang.Object.wait(Object.java:502)
at org.apache.felix.scr.impl.ComponentActorThread.run(ComponentActorThread.java:74)
- locked <0x00000000e260c920> (a java.util.LinkedList)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- None
"pool-7-thread-1" prio=10 tid=0x00007f5ce5134800 nid=0xba7 waiting on condition [0x00007f5ceaceb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000e260cb78> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:386)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
Locked ownable synchronizers:
- None
解决方案 As Guillaume has mentioned on the Google Groups site, this is because Play continuations only work on the inbuilt Netty server. You are entirely correct that this information is lacking from the documentation, but it is simply a case that only using Netty does Play have control over the request thread. For all the other servers, Play needs to create a wrapper around the servlet API, meaning that a thread cannot be held by Play.
Unfortunately, this is one of the trade-offs when using Play deployed to anything other than the preferred platform.
这篇关于Play持续保持http线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!