ExecutorService with Timeout for Interruptable Tasks
Apabila melaksanakan tugas secara serentak, selalunya diingini untuk mempunyai mekanisme untuk mengganggu tugasan yang melampaui batas yang ditentukan. tamat masa. Ini amat berguna dalam situasi di mana tugasan yang berjalan lama boleh membawa kepada lokap aplikasi atau isu prestasi.
Melaksanakan TimeoutExecutorService
Berikut ialah pelaksanaan TimeoutThreadPoolExecutor yang memanjangkan Standard ThreadPoolExecutor dan menggabungkan tamat masa ciri:
class TimeoutThreadPoolExecutor extends ThreadPoolExecutor { private final long timeout; private final TimeUnit timeoutUnit; private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); private final ConcurrentMap<Runnable, ScheduledFuture> runningTasks = new ConcurrentHashMap<>(); public TimeoutThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, long timeout, TimeUnit timeoutUnit) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); this.timeout = timeout; this.timeoutUnit = timeoutUnit; } // Override methods to implement timeout behavior @Override protected void beforeExecute(Thread t, Runnable r) { if (timeout > 0) { ScheduledFuture scheduled = timeoutExecutor.schedule(new TimeoutTask(t), timeout, timeoutUnit); runningTasks.put(r, scheduled); } } @Override protected void afterExecute(Runnable r, Throwable t) { ScheduledFuture timeoutTask = runningTasks.remove(r); if (timeoutTask != null) { timeoutTask.cancel(false); } } // Timeout task to interrupt threads class TimeoutTask implements Runnable { private final Thread thread; public TimeoutTask(Thread thread) { this.thread = thread; } @Override public void run() { thread.interrupt(); } } }
Penggunaan:
Untuk menggunakan TimeoutThreadPoolExecutor, anda hanya boleh membuat instantiate dengan nilai tamat masa:
TimeoutThreadPoolExecutor executor = new TimeoutThreadPoolExecutor( 4, // corePoolSize 8, // maximumPoolSize 1, // keepAliveTime TimeUnit.SECONDS, // timeUnit new LinkedBlockingQueue<>(), // workQueue 5, // timeout TimeUnit.SECONDS // timeoutUnit );
Kemudian , serahkan tugas kepada pelaksana sebagai biasa:
executor.submit(() -> { // long-running task });
Jika tugasan mengambil masa lebih lama daripada tamat masa yang ditentukan, urutan yang melaksanakan tugasan akan terganggu, menyebabkan tugasan ditamatkan dengan baik.
Penyelesaian Alternatif
Satu lagi pendekatan untuk melaksanakan tamat masa untuk tugasan ialah menggunakan ScheduledExecutorService sebagai dicadangkan dalam jawapan. Ini melibatkan penyerahan tugas sebagai Boleh Dipanggil dan mengekalkan masa depan yang dicipta. Tugasan kedua kemudiannya boleh dijadualkan untuk membatalkan masa hadapan selepas tempoh tertentu, dengan berkesan mengganggu tugasan itu.
Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Melaksanakan Tamat Masa untuk Tugasan Boleh Terganggu dalam Perkhidmatan Pelaksana?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!