play framework 中使用线程 及 锁的问题

在controller的action中使用锁和线程 要特别小心,最好不要使用。

这是由于play在处理多个请求时实际上是复用的一个线程,而不像struts之类的框架,每个请求一个线程一个对象。

所以如下例子中

public class TestC extends Controller{
      public static void t(){
           synchronized(TestC.class){
               Thread.sleep(10000);
           }
           ok();
      }
  
      public static void t2(){
           ok();
      }
}
你会发现 不仅是 路由 t 的请求被阻塞,就连t2的请求也被阻塞了,play框架在处理所有请求时 只使用了若干个有限的线程进行线程复用,个数一般和CPU核心相等,主要是为了提高性能,比较频繁的创建和销毁线程是比较重的行为。

那要例子中的操作应该怎么办呢?play引入了await方法和Promise对象 ,Promise继承了java 并发框架中的Future

这样写

Promise<String> delayedResult = veryLongComputation(…);
String result = await(delayedResult);

具体示例就是

await(new Job<Long>(){
	@Override
	public Long doJobWithResult() throws Exception {
			synchronized(TestC.class){
			   Thread.sleep(10000);
		    }
			return null;
	}
}.now())
这样其实就开启了另外一个线程,本次请求被挂起但是线程并未阻塞,其它请求仍然可用

参考:https://www.playframework.com/documentation/1.3.x/asynchronous 的Continuations部分的内容




©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页