自旋任务

自旋锁

由于业务场景需要,需要对一个任务做自旋等待其结果,在网上也没找到相似的代码和应用场景就自己实现了一个自旋任务,算是解决了工作中的场景,然而能力有限,所以来跟大家一起学习,听听大家的意见和指导。

@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();



    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java中的多线程编程面临的一个重要问题就是竞争条件,即多个线程同时访问共享资源时可能导致数据不一致的问题。为了避免这种情况,使用锁来控制线程的访问顺序是常见的一种方。在锁的实现中,使用自旋等待的方可以提高锁的效率和性能。 在Java中,任务执行可以使用线程来实现。当多个线程同时访问同一个任务时,需要使用锁来避免竞争条件的发生。自旋等待的方可以为竞争的线程提供更高效的访问策略。 具体来说,当一个线程需要获取锁时,如果发现锁已经被其他线程占用,该线程将一直尝试获取锁,直到获得锁为止。这种尝试获取锁的行为称为自旋等待。 在Java中,可以使用synchronized关键字实现锁的机制,同时配合使用wait()和notify()方法实现自旋等待。当一个线程需要访问任务时,首先通过synchronized关键字获取任务的锁,如果发现任务已经被其他线程占用,则使用wait()方法让当前线程进入等待状态。当其他线程释放了任务的锁时,会使用notify()方法通知正在等待的线程来尝试获取锁。被通知的线程会重新尝试获取锁,直到成功获取为止。 使用自旋等待的方可以提高锁的效率和性能,因为等待时间较短,线程不需要频繁地进入阻塞状态,而是通过反复尝试获取锁来增加锁的使用率。但是需要注意,自旋等待也会增加CPU的使用率,因此要权衡锁的使用效果和CPU的使用效率。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值