自旋锁
由于业务场景需要,需要对一个任务做自旋等待其结果,在网上也没找到相似的代码和应用场景就自己实现了一个自旋任务,算是解决了工作中的场景,然而能力有限,所以来跟大家一起学习,听听大家的意见和指导。
@Slf4j
public class SpinLockOperator<T> {
private Predicate predicate;
private SpinLockTask<T> task;
private volatile boolean flag = true;
private Long timeout;
private Long period;
/**
*
* @param predicate 自旋终止条件
* @param task 线程任务
* @param period 自旋任务间隔时间 ms
* @param timeout 自选任务最大执行时间 ms
*/
public SpinLockOperator(Predicate predicate,SpinLockTask task,Long period,Long timeout) {
this.predicate = predicate;
this.task = task;
this.timeout = timeout;
this.period = period;
}
public T submit(){
Future<T> future = Executors.newFixedThreadPool(10).submit(new Callable<T>() {
@Override
public T call() throws Exception {
Object obj = null;
while(flag){
obj = task.doTask();
if(predicate.test(obj)){
flag = false;
}
Thread.sleep(period);
}
return (T)obj;
}
});
T result = null;
try {
result = future.get(timeout, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
log.error("自选任务超时,执行任务task:{}",task.getClass());
future.cancel(true);
}
return result;
}
}
public interface SpinLockTask<T> {
T doTask();
}
测试类
这里predicate是自选任务终止条件,period表示自旋周期,timeout最大阻塞时间,spinLockTask内是自旋任务
public class Main {
private volatile boolean flag = true;
@Test
public void testMain(){
Predicate p = o -> o!= null;
String result = new SpinLockOperator<String>(p, new SpinLockTask<String>() {
@Override
public String doTask() {
return "success";
}
},100L,3000L).submit();
}
}