복붙노트

[SPRING] ThreadPoolTaskExecutor로부터 호출 가능해, 또는 Runnable를 Callable에 캐스트 할 수있다

SPRING

ThreadPoolTaskExecutor로부터 호출 가능해, 또는 Runnable를 Callable에 캐스트 할 수있다

Callable 인터페이스의 구현 인 내 작업을 실행하기 위해 ThreadPoolTaskExecutor를 사용하고 있습니다. 태스크가 여전히 풀 (모니터링)에 있는지 만 확인하고 싶습니다. 그렇게하는 방법? ThreadPoolExecutor에서 큐를 가져올 수 있지만 Runnable을 호출 가능하도록 어떻게 캐스팅 할 수 있습니까?

기본적으로 나는이 callable

public interface IFormatter extends Callable<Integer>{
    Long getOrderId();
}

나는 이것을 이렇게 실행하고있다.

ThreadPoolExecutor.submit(new Formatter(order));

그리고 마지막으로 일부 비동기 메서드에서 ExecutorService 큐를 반복하고 orderId 스레드가 여전히 있는지 확인하고 싶습니다.

해결법

  1. ==============================

    1.이 답변에서 설명했듯이 Callable을 수동으로 만들고 실행을 통해 대기열에 넣어서 FutureTask를 제어 할 수 있습니다. 그렇지 않은 경우는, Callable를 ExecutorService 고유의 객체에 랩 해 대기열에 넣어, 표준 API를 사용해 Callable의 프로퍼티를 조회 할 수 없게됩니다.

    이 답변에서 설명했듯이 Callable을 수동으로 만들고 실행을 통해 대기열에 넣어서 FutureTask를 제어 할 수 있습니다. 그렇지 않은 경우는, Callable를 ExecutorService 고유의 객체에 랩 해 대기열에 넣어, 표준 API를 사용해 Callable의 프로퍼티를 조회 할 수 없게됩니다.

    커스텀 FutureTask 사용하기

    class MyFutureTask extends FutureTask<Integer> {
        final IFormatter theCallable;
    
        public MyFutureTask(IFormatter callable) {
            super(callable);
            theCallable=callable;
        }
        Long getOrderId() {
            return theCallable.getOrderId();
        }
    }
    

    threadPoolExecutor.execute (새로운 MyFutureTask (새로운 포매터 (순서)));

    대기열에서 주문 ID를 쿼리 할 수 ​​있습니다.

    public static boolean isEnqueued(ThreadPoolExecutor e, Long id) {
        for(Object o: e.getQueue().toArray()) {
            if(o instanceof MyFutureTask && Objects.equals(((MyFutureTask)o).getOrderId(), id))
                return true;
        }
        return false;
    }
    

    이것은 임의의 ExecutorService (큐를 가지고 있다고 가정)에서 작동합니다. ThreadPoolExecutor만을 사용하는 경우, 제출자에게 의존하는 대신 FutureTask 인스턴스 생성 (Java 6로 시작)을 사용자 정의 할 수 있습니다.

    public class MyThreadPoolExecutor extends ThreadPoolExecutor {
    
        public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                    TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }
        public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
            TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory);
        }
        public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
            TimeUnit unit, BlockingQueue<Runnable> workQueue,
            RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, handler);
        }
        public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
            TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
            RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory, handler);
        }
    
        @Override
        protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
            if(callable instanceof IFormatter)
                return (FutureTask<T>)new MyFutureTask((IFormatter)callable);
            return super.newTaskFor(callable);
        }
    }
    

    그런 다음 ThreadPoolExecutor 대신 MyThreadPoolExecutor 인스턴스를 사용하여 IFormatter 인스턴스를 제출하면 표준 FutureTask 대신 MyFutureTask를 사용하여 자동으로 래핑됩니다. 단점은이 특정 ExecutorService에서만 작동하며 일반 메서드는 특수 처리에 대한 검사되지 않은 경고를 생성한다는 것입니다.

  2. ==============================

    2.ExecutorService를 모니터링하려는 것처럼 보이므로 decorateTask ()를 재정의하십시오. 그런 다음 미래를 장식하여 상태를 모니터 할 수 있습니다.

    ExecutorService를 모니터링하려는 것처럼 보이므로 decorateTask ()를 재정의하십시오. 그런 다음 미래를 장식하여 상태를 모니터 할 수 있습니다.

  3. from https://stackoverflow.com/questions/30789402/get-callable-from-threadpooltaskexecutor-or-cast-runnable-to-callable by cc-by-sa and MIT license