如何让java.util.concurrent.Executor或CompletionService在Google AppEngine上运行?这些类都是officially white-listed,但在尝试提交异步任务时遇到运行时安全性错误。
代码:
// uses the async API but this factory makes it so that tasks really
// happen sequentially
Executor executor = java.util.concurrent.Executors.newSingleThreadExecutor();
// wrap Executor in CompletionService
CompletionService<String> completionService =
new ExecutorCompletionService<String>(executor);
final SomeTask someTask = new SomeTask();
// this line throws exception
completionService.submit(new Callable<String>(){
public String call() {
return someTask.doNothing("blah");
}
});
// alternately, send Runnable task directly to Executor,
// which also throws an exception
executor.execute(new Runnable(){
public void run() {
someTask.doNothing("blah");
}
});
}
private class SomeTask{
public String doNothing(String message){
return message;
}
}
例外:
java.security.AccessControlException: 拒绝访问 (java.lang.RuntimePermission modifyThreadGroup)at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) 在 java.security.AccessController.checkPermission(AccessController.java:546) 在 java.lang.SecurityManager.checkPermission(SecurityManager.java:532) 在 com.google.appengine.tools.development.DevAppServerFactory $ CustomSecurityManager.checkPermission(DevAppServerFactory.java:166) 在 com.google.appengine.tools.development.DevAppServerFactory $ CustomSecurityManager.checkAccess(DevAppServerFactory.java:191) 在 java.lang.ThreadGroup.checkAccess(ThreadGroup.java:288) 在 java.lang.Thread.init(Thread.java:332) 在 java.lang.Thread中。(Thread.java:565) 在 java.util.concurrent.Executors $ DefaultThreadFactory.newThread(Executors.java:542) 在 java.util.concurrent.ThreadPoolExecutor.addThread(ThreadPoolExecutor.java:672) 在 java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:697) 在 java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652) 在 java.util.concurrent.Executors $ DelegatedExecutorService.execute(Executors.java:590) 在 java.util.concurrent.ExecutorCompletionService.submit(ExecutorCompletionService.java:152)
在Tomcat上运行或通过命令行JVM运行时,此代码可以正常工作。但是,它在AppEngine SDK Jetty容器中窒息(尝试使用Eclipse插件和maven-gae-plugin)。
AppEngine可能设计为不允许运行潜在危险的程序,因此我可以看到它们完全禁用线程创建。但是,谷歌为什么允许你创建一个类,但不允许你调用它的方法?白名单java.util.concurrent具有误导性。
还有其他方法可以在GAE上执行并行/同时/并发任务吗?
答案 0 :(得分:11)
的文档中更清楚地说明了这一点应用程序无法生成线程
<强>线程强>
Java应用程序无法创建新的
java.lang.ThreadGroup
或新的java.lang.Thread
。这些限制也适用于使用线程的JRE类。例如,应用程序无法创建新的java.util.concurrent.ThreadPoolExecutor
或java.util.Timer
。应用程序可以对当前线程执行操作,例如Thread.currentThread().dumpStack()
。
也许白名单是这样的,您可以使用接受Executors
的库,并且您可以提供自己的Executor
来执行当前线程中的工作。
您可以尝试实验Task Queues
答案 1 :(得分:1)