最近項目中遇到了一個新的需求,就是實現(xiàn)一個可以動態(tài)添加定時任務(wù)的功能。說到這里,有人可能會說簡單啊,使用quartz就好了,簡單粗暴。然而quartz框架太重了,小項目根本不好操作啊。當然,也有人會說,jdk提供了timer的接口啊,完全夠用啊。但是我們項目的需求完全是多線程的模型啊,而timer是單線程的,so,樓主最后還是選擇了jdk的線程池。
在成都網(wǎng)站建設(shè)、做網(wǎng)站中從網(wǎng)站色彩、結(jié)構(gòu)布局、欄目設(shè)置、關(guān)鍵詞群組等細微處著手,突出企業(yè)的產(chǎn)品/服務(wù)/品牌,幫助企業(yè)鎖定精準用戶,提高在線咨詢和轉(zhuǎn)化,使成都網(wǎng)站營銷成為有效果、有回報的無錫營銷推廣。創(chuàng)新互聯(lián)公司專業(yè)成都網(wǎng)站建設(shè)10余年了,客戶滿意度97.8%,歡迎成都創(chuàng)新互聯(lián)客戶聯(lián)系。
線程池是什么
Java通過Executors提供四種線程池,分別為:
newCachedThreadPool :創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
newFixedThreadPool : 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待。
newScheduledThreadPool : 創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行。
newSingleThreadExecutor : 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。
樓主項目中用到的是newScheduledThreadPool, 就這些吧,再多的樓主就班門弄斧了,Google一下,一大堆。
線程池service的獲取
樓主通過單例模式來獲取線程池的service,代碼如下:
/** * 線程池創(chuàng)建. * @author wuhf * @date 2018/01/16 */ public class ThreadPoolUtils { private static ScheduledExecutorService executorService; private ThreadPoolUtils() { //手動創(chuàng)建線程池. executorService = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.Builder().namingPattern("syncdata-schedule-pool-%d").daemon(true).build()); } private static class PluginConfigHolder { private final static ThreadPoolUtils INSTANCE = new ThreadPoolUtils(); } public static ThreadPoolUtils getInstance() { return PluginConfigHolder.INSTANCE; } public ScheduledExecutorService getThreadPool(){ return executorService; } }
中斷某一個正在運行的線程代碼實現(xiàn)
廢話就不多說了,代碼如下:
/** * 中斷線程池的某個任務(wù). */ public class InterruptThread implements Runnable { private int num; public InterruptThread (int num){ this.num = num; } public static void main(String[] args) throws InterruptedException { Thread interruptThread = new Thread(new InterruptThread(1)); ScheduledFuture<?> t = ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread,0,2, TimeUnit.SECONDS); InterruptThread interruptThread1 = new InterruptThread(2); ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread1,0,2, TimeUnit.SECONDS); InterruptThread interruptThread2 = new InterruptThread(3); ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread2,0,2, TimeUnit.SECONDS); Thread.sleep(5000); //終止正在運行的線程interruptThread t.cancel(true); while (true){ } } @Override public void run() { System.out.println("this is a thread" + num); } }
踩坑記錄
樓主在使用如下代碼時,突然想到當這個定時任務(wù)需要被停止時該如何停止線程運行
ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread,0,2, TimeUnit.SECONDS);
既然我有這樣的需求,那就Google一下吧,找了大半圈,愣是沒找到相關(guān)資料,都是一些關(guān)于Java線程池的深入分析?;蛘呤侨肿兞可兜?,并沒有找到令樓主滿意的解決方案。
既然沒有線程的那就扒一下scheduleAtFixedRate的底層源碼看看是什么東西吧,果不其然我在源碼中看到了scheduleAtFixedRate方法的具體實現(xiàn),發(fā)現(xiàn)他的返回值是ScheduledFuture。
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) { if (command == null || unit == null) throw new NullPointerException(); if (period <= 0) throw new IllegalArgumentException(); ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(command, null, triggerTime(initialDelay, unit), unit.toNanos(period)); RunnableScheduledFuture<Void> t = decorateTask(command, sft); sft.outerTask = t; delayedExecute(t); return t; }
接著往下我們再看看ScheduledFuture里面有什么東西吧,沒有讓樓主失望,看到了這個
public boolean cancel(boolean mayInterruptIfRunning) { boolean cancelled = super.cancel(mayInterruptIfRunning); if (cancelled && removeOnCancel && heapIndex >= 0) remove(this); return cancelled; } //從線程的運行隊列中移除當前線程 public boolean remove(Runnable task) { boolean removed = workQueue.remove(task); tryTerminate(); // In case SHUTDOWN and now empty return removed; }
再往上查super.cancel(mayInterruptIfRunning)是什么東西,我們看到了這個,
//通過調(diào)用線程的interrupt方法終止線程運行 public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); } } } finally { finishCompletion(); } return true; }
到這里所有的問題都迎刃而解。
總結(jié)一下吧
項目中總是會遇到比較難搞的解決方案,當Google不太好找時,翻一下jdk的源碼或許也是一個不錯的方法。
文章標題:Java實現(xiàn)終止線程池中正在運行的定時任務(wù)
URL分享:http://m.newbst.com/article30/jhshpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、ChatGPT、品牌網(wǎng)站設(shè)計、網(wǎng)站設(shè)計公司、全網(wǎng)營銷推廣、營銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)