简体   繁体   中英

ScheduleAtFixedRate executes once (or as many times as corePoolSize equals)

I have created MyThreadPoolExecutor

public class MyThreadPoolExecutor extends ScheduledThreadPoolExecutor {
    private final Context ctx;

    public MyThreadPoolExecutor(int corePoolSize, Context ctx, String threadNamePrefix)
    {
        super(corePoolSize);
        MyThreadFactory factory = new MyThreadFactory(new ThreadExceptionHandler(ctx), threadNamePrefix);
        setThreadFactory(factory);
        this.ctx = ctx;
    }

    @Override
    public void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        LogUtils.i(Tags.THREAD_EXECUTED, Thread.currentThread().getName());

        if (t == null && r instanceof Future<?>) {
            try {
                Object result = ((Future<?>) r).get();
            } catch (CancellationException e) {
                t = e;
            } catch (ExecutionException e) {
                t = e.getCause();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }

        if (t != null) {
            LogUtils.e(Tags.UNCAUGHT_EXCEPTION, "Uncaught exception error");
            Utils.handleUncaughtException(ctx, t);
        }
    }
}

I have MyThreadFactory

public class MyThreadFactory implements ThreadFactory {
private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
private final Thread.UncaughtExceptionHandler handler;
private final String threadName;

public MyThreadFactory(Thread.UncaughtExceptionHandler handler, @NonNull String threadName) {
    this.handler = handler;
    this.threadName = threadName;
}

@Override
public Thread newThread(@NonNull Runnable runnable) {
    Thread thread = defaultFactory.newThread(runnable);
    thread.setUncaughtExceptionHandler(handler);
    if (threadName != null) {
        thread.setName(threadName +"-" + thread.getId());
    }
    LogUtils.i(Tags.THREAD_CREATED, thread.getName());
    return thread;
}

}

I need to execute thread every 1 second to do some stuff. When I use my own MyScheduledThreadPoolExecutor it runs only as many times as corePoolSize equals. So when corePoolSize equals 3, my thread runs 3 times.

When I use ScheduledThreadPoolExecutor the above problem does not exist.

Below the way I run it:

commander = new MyThreadPoolExecutor(corePoolSize, getApplicationContext(), threadNamePrefix);
commander.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            LogUtils.i(Tags.DISPLAY_ACTIVITY, "Check display " + Thread.currentThread().getName());
        }
    }, 1000, PERIOD_CHECK_TIME_FRAME, TimeUnit.MILLISECONDS);

What am I missing? What am I doing wrong?

ScheduledExecutorService blocks subsequent invocation if a runtime exception occurs while executing the runnable without throwing the exception (Really sad).

This might be your issue. Probably some where the code is throwing exception and therefore no more invocations ever happen. Try wrapping the runnable inside a try catch to see if there is any exception thrown.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM