以下虚拟场景:某个接口业务处理耗时不确定,要优化前台交互~
(1)使用多线程异步处理,不管成功与否都返回一个状态,例如正在处理中;
(2)设置限时时常,超时后按业务自定义返回;
我们接下来就是用第二种方式:
1.首先自定义一个抽象类:
public abstract class goRunnable implements Runnable {
abstract void go();
private CountDownLatch countDownLatch;
public goRunnable(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
if (countDownLatch.getCount() != 1) {
throw new RuntimeException("countDownLatch count should be 1");
}
go();
countDownLatch.countDown();
}
}
2.集成抽象类,定义业务方法:
public class MyTask extends goRunnable {
public MyTask(CountDownLatch countDownLatch) {
super(countDownLatch);
}
@Override
void go() {
//业务.....
}
}
3.编写接口:
@PostMapping("/api")
public BaseResult api() throws InterruptedException {
CountDownLatch count = new CountDownLatch(1);
MyTask task = new MyTask(count);
ThreadPoolExecutor pool = ThreadPoolUtil.POOL.getPool();
pool.execute(task);
//设置超时时长
boolean await = count.await(1, TimeUnit.SECONDS);
//根据状态判断返回参数
return await ? BaseResult.success() : BaseResult.failure("");
}
使用到了适配器模式,并且使用到了CountDownLatch来控制多线程同步,深入了解CountDownLatch及future后可以更底层一点的实现功能~如果你有更好的方法请留言
当然还可以使用future来实现类似:
@Test
public void t4() throws ExecutionException, InterruptedException {
ThreadPoolExecutor pool = ThreadPoolUtil.POOL.getPool();
Future<?> submit = pool.submit(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("测试");
});
try {
submit.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("超时");
}
}
当然还有比较优雅的方式使用DeferredResult