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

本文探讨了在Play框架中为何不应在控制器的Action中使用锁和线程,因为这会导致请求处理阻塞。文章介绍了如何利用Promise和await来实现异步操作,以避免阻塞并提高应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在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部分的内容




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值