在play框架中异步执行代码块的问题

时间:2013-05-02 09:34:35

标签: java asynchronous playframework playframework-2.0

我正在使用amazon s3上传照片作为我的服务。 根据{{​​3}},代码必须是阻止代码。

“当您的代码可能阻止时包括: 通过第三方客户端库使用REST / WebService API(即,不使用Play的异步WS API)“。

“请注意,您可能想要将您的阻止代码包装在Futures中。这不会使其无阻塞,它只是意味着阻塞将在不同的线程中发生。您仍然需要确保线程池你正在使用那里有足够的线程来处理阻塞。“

但现在我的代码是:

return async(
    future(new Callable<String>() {
        public String call() {
            return OP.upload(Req, name); //upload phoho with s3
        }   
     }).map(new F.Function<String,Result>() {
         public Result apply(String i) {
            return ok(i);
         }
     })

它等于下面的代码吗? (因为我通过第三方客户端库使用WebService API)

     return OP.upload(Req, name);

如果我仍然使用异步方法会有任何问题吗?

我问这是因为我的服务器已经粉碎了一些时间。 转储信息是:

 "application-akka.actor.default-dispatcher-231" prio=10 tid=0x00007fc994101000 nid=0x5964 waiting for monitor entry [0x00007fc9f6608000]
   java.lang.Thread.State: BLOCKED (on object monitor)
at java.util.jar.Attributes.read(Attributes.java:394)
at java.util.jar.Manifest.read(Manifest.java:199)
at java.util.jar.Manifest.<init>(Manifest.java:69)
at java.util.jar.JarFile.getManifestFromReference(JarFile.java:182)
at java.util.jar.JarFile.getManifest(JarFile.java:163)
at sun.misc.URLClassPath$JarLoader$2.getManifest(URLClassPath.java:710)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:238)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
- locked <0x0000000715dd6038> (a sun.misc.Launcher$AppClassLoader)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
- locked <0x0000000715dd6038> (a sun.misc.Launcher$AppClassLoader)
  ...

我们可以看到资源&lt; 0x0000000715dd6038&gt;锁住了。同时,所有其他线程都在等待此资源。然后系统停了下来。强制阻止代码以ascy方式运行会导致问题吗?

1 个答案:

答案 0 :(得分:0)

你正在包装阻塞调用的方式是正确的,这不会导致问题(但可能是第三方客户端库导致问题)。 关于S3通信,我建议使用非阻塞/异步api,例如jclouds有异步操作(然后你需要将java Future转换为play Promise),或者尝试只使用play的WS。