線程與線程池的應(yīng)用

異步任務(wù)AsyncTask 源碼 地址http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/os/AsyncTask.java

最近在Android開發(fā)上遇到線程遇到諸多問題吃嘿,特此記錄下嚎卫。也希望能為諸君貢獻(xiàn)一二嫌拣。

Code一版

直接使用new Thread


        new Thread(new Runnable() {
                @Override
                public void run() {
                    doSomething();//執(zhí)行代碼(耗時(shí)等 數(shù)據(jù)庫操作等)
                }
            }).start();

很明顯的弊端,Code中太多地方需要線程的地方锚赤,new 了無數(shù)個(gè)線程。
1.每次new Thread新建對象性能差
2. 線程缺乏統(tǒng)一管理调违,可能無限制新建線程汽烦,相互之間競爭,即可能占用過多的系統(tǒng)資源導(dǎo)致死機(jī)
3.缺乏更多功能屹篓,比如定時(shí)執(zhí)行疙渣,定期執(zhí)行,線程中斷堆巧。
總之最后很扎心妄荔,而且你能想象這放在一個(gè)性能很差的Android機(jī)里面運(yùn)行么~~


Code二版

使用定義的線程池


先來個(gè)我定義的

/**
 * 線程池管理(線程統(tǒng)一調(diào)度管理)
 */
public final class ThreadPoolManager {

    public static class ThreadPoolProxy {
        ThreadPoolExecutor mExecutor;
        private int mCorePoolSize;
        private int mMaximumPoolSize;
        /**
         * @param corePoolSize    核心池的大小
         * @param maximumPoolSize 最大線程數(shù)
         */
        public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
            mCorePoolSize = corePoolSize;
            mMaximumPoolSize = maximumPoolSize;
        }

        /**
         * 初始化ThreadPoolExecutor
         * 雙重檢查加鎖,只有在第一次實(shí)例化的時(shí)候才啟用同步機(jī)制,提高了性能
         */
        private void initThreadPoolExecutor() {
            if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                synchronized (ThreadPoolProxy.class) {
                    if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
                        long keepAliveTime = 3000;
                        TimeUnit unit = TimeUnit.MILLISECONDS;
                        BlockingQueue workQueue = new LinkedBlockingDeque<>();
                        ThreadFactory threadFactory = Executors.defaultThreadFactory();
                        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();

                        mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
                                threadFactory, handler);
                    }
                }
            }
        }
        /**
         執(zhí)行任務(wù)和提交任務(wù)的區(qū)別?
         1.有無返回值
         execute->沒有返回值
         submit-->有返回值
         2.Future的具體作用?
         1.有方法可以接收一個(gè)任務(wù)執(zhí)行完成之后的結(jié)果,其實(shí)就是get方法,get方法是一個(gè)阻塞方法
         2.get方法的簽名拋出了異常===>可以處理任務(wù)執(zhí)行過程中可能遇到的異常
         */
        /**
         * 執(zhí)行任務(wù)
         */
        public void execute(Runnable task) {
            initThreadPoolExecutor();
            mExecutor.execute(task);
        }

        /**
         * 提交任務(wù)
         */
        public Future submit(Runnable task) {
            initThreadPoolExecutor();
            return mExecutor.submit(task);
        }

        /**
         * 移除任務(wù)
         */
        public void remove(Runnable task) {
            initThreadPoolExecutor();
            mExecutor.remove(task);
        }
    }

    /**
     * 線程池工廠類
     * Created by Samson on 2018/2/11.
     * 使用方法
     * ThreadPoolProxyFactory .getNormalThreadPoolProxy().execute(Runnable);
     */

    public static class ThreadPoolProxyFactory {
        private static ThreadPoolProxy mNormalThreadPoolProxy;
        private static ThreadPoolProxy mDownLoadThreadPoolProxy;

        /**
         * 得到普通線程池代理對象mNormalThreadPoolProxy
         */
        public static ThreadPoolProxy getNormalThreadPoolProxy() {
            if (mNormalThreadPoolProxy == null) {
                synchronized (ThreadPoolProxyFactory.class) {
                    if (mNormalThreadPoolProxy == null) {
                        mNormalThreadPoolProxy = new ThreadPoolProxy(10 , 10);
                    }
                }
            }
            return mNormalThreadPoolProxy;
        }
        /**
         * 下載專用
         * 得到下載線程池代理對象mDownLoadThreadPoolProxy
         */
        public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
            if (mDownLoadThreadPoolProxy == null) {
                synchronized (ThreadPoolProxyFactory.class) {
                    if (mDownLoadThreadPoolProxy == null) {
                        mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
                    }
                }
            }
            return mDownLoadThreadPoolProxy;
        }
    }
}

如何使用:

ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
                  .execute(new Runnable() {
                                  @Override
                                    public void run() {
                                          doSomething();
                                     }
                 });
-----------------------------------------lambda
ThreadPoolManager.ThreadPoolProxyFactory.getNormalThreadPoolProxy()
        .execute(() -> {doSomething();});

Code三版

手動控制版線程池(將所有事務(wù)分類放在規(guī)定的線程中執(zhí)行,(未不同類別的事務(wù)規(guī)定不同的線程))


/**
 * 本地?cái)?shù)據(jù)處理和耗時(shí)處理用不同線程處理
 */

public class ThreadPoolUtil {

    private List<Run> runList = new ArrayList<>();
    private List<Run> runListTemp = new ArrayList<>();
    private Thread thread = null;

    public interface Run {
        void run();
    }

    private ThreadPoolUtil() {
        init();
    }

    private void init() {
        if (thread == null) {
            thread = new Thread(() -> {
                for (; ; ) {
                    synchronized (lock) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    dealRun();
                }
            });
            thread.start();
        }
    }

    private final Object lock = new Object();
    private static ThreadPoolUtil _INSTANCESEND = null;
    private static ThreadPoolUtil _INSTANCESERVER = null;
    private static ThreadPoolUtil _INSTANCENORMAL = null;

    /**
     *  發(fā)消息
     * @return
     */
    public static ThreadPoolUtil getSendMsgInstance() {
        if (_INSTANCESEND == null) {
            _INSTANCESEND = new ThreadPoolUtil();
        }
        return _INSTANCESEND;
    }
    /**
     *  收消息
     * @return
     */
    public static ThreadPoolUtil getGetMsgInstance() {
        if (_INSTANCESERVER == null) {
            _INSTANCESERVER = new ThreadPoolUtil();
        }
        return _INSTANCESERVER;
    }
    /**
     *  普通通用消息
     * @return
     */
    public static ThreadPoolUtil getNormalInstance() {
        if (_INSTANCENORMAL == null) {
            _INSTANCENORMAL = new ThreadPoolUtil();
        }
        return _INSTANCENORMAL;
    }


    public void addRun(Run run) {
        runListTemp.add(run);
        synchronized (lock) {
            runList.addAll(runListTemp);
            runListTemp.clear();
            lock.notify();
        }
    }

    private Run getRun() {
        if (runList.size() <= 0) {
            return null;
        }
        Run run = null;
        synchronized (lock) {
            run = runList.get(0);
            runList.remove(0);
        }
        return run;
    }

    private void dealRun() {
        try {
            for (Run run = getRun(); (run) != null; ) {
                run.run();
                run = getRun();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

如何使用:不同的分類可 get 不同的線程來處理。

ThreadPoolUtil.getNormalInstance().addRun(new ThreadPoolUtil.Run() {
                @Override
                public void run() {
                     doSomething();
                }
            });
-----------------------------------------lambda
ThreadPoolUtil.getNormalInstance().addRun(() ->{
                doSomething();
            });

2,3兩種方式 區(qū)別

2方式一旦有線程操作失誤可能會導(dǎo)致全線線程癱瘓,導(dǎo)致整個(gè)線程池?zé)o法正常的運(yùn)行下去航背,
3方式使用失誤 基本只會導(dǎo)致其一線程癱瘓玖媚,更易于查找 修復(fù)今魔。

至于其他優(yōu)勢 仍在探究中...

如有紕漏 敬請斧正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吟宦,一起剝皮案震驚了整個(gè)濱河市殃姓,隨后出現(xiàn)的幾起案子辰狡,更是在濱河造成了極大的恐慌娃磺,老刑警劉巖偷卧,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坐求,死亡現(xiàn)場離奇詭異桥嗤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)渊鞋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門儡湾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丹皱,你說我怎么就攤上這事∧佤ぃ” “怎么了根时?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵含友,是天一觀的道長辆童。 經(jīng)常有香客問我把鉴,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮鞠柄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好圈纺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布峻呛。 她就那樣靜靜地躺著杀饵,像睡著了一般惨远。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贺氓,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天蔚叨,我揣著相機(jī)與錄音,去河邊找鬼。 笑死蔑水,一個(gè)胖子當(dāng)著我的面吹牛邢锯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搀别,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丹擎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歇父?” 一聲冷哼從身側(cè)響起蒂培,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎榜苫,沒想到半個(gè)月后护戳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡单刁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年灸异,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羔飞。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡肺樟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逻淌,到底是詐尸還是另有隱情么伯,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布卡儒,位于F島的核電站田柔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏骨望。R本人自食惡果不足惜硬爆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望擎鸠。 院中可真熱鬧缀磕,春花似錦、人聲如沸劣光。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绢涡。三九已至牲剃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間雄可,已是汗流浹背凿傅。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工缠犀, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人狭归。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓夭坪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親过椎。 傳聞我的和親對象是個(gè)殘疾皇子室梅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,374評論 8 265
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)疚宇,斷路器亡鼠,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    小徐andorid閱讀 2,808評論 3 53
  • 問自己 世間有多少美好 不能去填滿躁動的心 如果感覺到虛空 可以琴棋書畫 柴米油鹽 俗或雅,煙火或詩意 都源自愛 ...
    秋瓷大小姐閱讀 293評論 0 0
  • 一個(gè)人只擁有此生此世是不夠的敷待,他還應(yīng)該擁有詩意的世界间涵。——王小波 活動流程 一 會前音樂 二 主持人開場詞和會...
    yeld小野閱讀 229評論 0 3