Android中的線程通訊

線程

android中的線程是執(zhí)行Runnable接口的Thread

代碼如下

new Thread(new Runnable() {
            @Override
            public void run() {
                //設(shè)置線程優(yōu)先級(jí)吉拳,減少與UI線程的競(jìng)爭(zhēng)
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
            }
        }).start();

代碼執(zhí)行在Runnable.run()里面萎战。
通過android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND)可以設(shè)置線程的優(yōu)先級(jí)別绣夺,減少線程與UI線程的競(jìng)爭(zhēng)纽门。
[除此以外android還提供了更好的選擇HandlerThread, AsyncTask, 和IntentService.]

線程池

ThreadPoolExecutor能管理程序伤疙,開發(fā)者只需要把線程加入線程隊(duì)列即可悼吱。
創(chuàng)建線程池的時(shí)候需要舒適化一些參數(shù)慎框,見下面代碼,摘抄自阿里巴巴的ANDROID開發(fā)手冊(cè)

        //獲取可用cpu核數(shù)量
        int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
        //運(yùn)行完后的存活時(shí)間
        int KEEP_ALIVE_TIME = 1;
        //運(yùn)行完后的存活時(shí)間的單位
        TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
        //存放線程的隊(duì)列
        BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<Runnable>();
        ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES,
                NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue,
                new BackgroundThreadFactory(), new DefaultRejectedExecutionHandler());
        //執(zhí)行任務(wù)
        executorService.execute(new Runnable() {
            @Override
            public void run() {

            }
        });
    //創(chuàng)建后臺(tái)線程
    private class BackgroundThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(@NonNull final Runnable r) {
            Runnable wrapperRunnable = new Runnable() {
                @Override
                public void run() {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    r.run();
                }
            };
            return new Thread(wrapperRunnable);
        }
    }
    /*拒絕策略后添,當(dāng)隊(duì)列滿后的處理方式笨枯,系統(tǒng)提供了
     *AbortPolicy
     *DiscardPolicy
     *DiscardOldestPolicy
     *CallerRunsPolicy
     */
    private class DefaultRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

        }
    }

線程通信

線程間通訊分為兩種,一種是和主線通訊遇西,一種是后臺(tái)線程之間通訊馅精。
當(dāng)與主線程通信的時(shí)候,是不可以阻塞主線程的粱檀,所以一般使用handler來(lái)通信洲敢。
先創(chuàng)建一個(gè)在UI線程的Handler

    Handler handler = new UiHandler();

    private static class UiHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    //更新UI等操作
                    break;
                default:
                    break;
            }
        }
 

然后執(zhí)行完耗時(shí)操作之后發(fā)消息給主線程去執(zhí)行UI操作

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                // 耗時(shí)操作
                handler.obtainMessage(1).sendToTarget();
            }
        });

后臺(tái)線程之間的通信主要涉及到同步與互斥。
如果在不同線程中操作同一數(shù)據(jù)茄蚯,可能造成數(shù)據(jù)讀寫狀態(tài)不同步压彭,那么我們就需要在每一次的讀寫中鎖住這個(gè)值。
如下兩個(gè)線程渗常。

      class RunableA implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class){
                Log.d("hah","A start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("hah","A end");
            }
        }
    }
    class RunableB implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class){
                Log.d("hah","b start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("hah","b END");
            }
        }
    }
        executorService.execute(new RunableA());
        executorService.execute(new RunableB());

打印如下:
14:56:53.083 3382-3395/activity.activitytest D/bruce: A start
14:56:55.083 3382-3395/activity.activitytest D/bruce: A end
14:56:55.153 3382-3396/activity.activitytest D/bruce: b start
14:56:57.153 3382-3396/activity.activitytest D/bruce: b END

可見B 是等 A 釋放之后才運(yùn)行的壮不。

再來(lái)看看wait和notify的應(yīng)用。

    class RunableA implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class) {
                Log.d("bruce", "A wait");
                try {
                    MainActivity.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Log.d("bruce", "A start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("bruce", "A end");
            }
        }
    }
    class RunableB implements Runnable{
        @Override
        public void run() {
            synchronized (MainActivity.class) {
                Log.d("bruce", "b start");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Log.d("bruce", "b END");
                MainActivity.class.notify();
            }
        }
    }

線程A 開始的時(shí)候先wait皱碘,然后在線程B結(jié)束的時(shí)候notify
打印如下:
15:17:34.423 4365-4378/? D/bruce: A wait
15:17:34.423 4365-4379/? D/bruce: b start
15:17:36.423 4365-4379/activity.activitytest D/bruce: b END
15:17:36.423 4365-4378/activity.activitytest D/bruce: A start
15:17:38.433 4365-4378/activity.activitytest D/bruce: A end

會(huì)發(fā)現(xiàn)先執(zhí)行A然后等待询一,接著開始制定B 等B notify之后又開始執(zhí)行A;

以上就是線程的簡(jiǎn)單應(yīng)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末健蕊,一起剝皮案震驚了整個(gè)濱河市菱阵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缩功,老刑警劉巖晴及,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異掂之,居然都是意外死亡抗俄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門世舰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人槽卫,你說我怎么就攤上這事跟压。” “怎么了歼培?”我有些...
    開封第一講書人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵震蒋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我躲庄,道長(zhǎng)查剖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任噪窘,我火速辦了婚禮笋庄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倔监。我一直安慰自己直砂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開白布浩习。 她就那樣靜靜地躺著静暂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谱秽。 梳的紋絲不亂的頭發(fā)上洽蛀,一...
    開封第一講書人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音疟赊,去河邊找鬼郊供。 笑死,一個(gè)胖子當(dāng)著我的面吹牛听绳,可吹牛的內(nèi)容都是我干的颂碘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼头岔!你這毒婦竟也來(lái)了塔拳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤峡竣,失蹤者是張志新(化名)和其女友劉穎靠抑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體适掰,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颂碧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了类浪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片载城。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖费就,靈堂內(nèi)的尸體忽然破棺而出诉瓦,到底是詐尸還是另有隱情,我是刑警寧澤力细,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布睬澡,位于F島的核電站,受9級(jí)特大地震影響眠蚂,放射性物質(zhì)發(fā)生泄漏煞聪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一逝慧、第九天 我趴在偏房一處隱蔽的房頂上張望昔脯。 院中可真熱鬧,春花似錦馋艺、人聲如沸栅干。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)布持。三九已至四瘫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仑乌。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工衣吠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贸弥,地道東北人迈螟。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像猬膨,于是被迫代替她去往敵國(guó)和親角撞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,095評(píng)論 25 707
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,404評(píng)論 0 17
  • 伸手擦了擦眼角不斷涌出的淚水谒所,我陷入了深深的沉思热康。腦子里亂亂糟糟的,但是我想記錄下自己的情緒劣领。 這幾天在一篇文章上...
    一棵奇思幻想的樹閱讀 275評(píng)論 1 1
  • 又遇上香云姐军,讓我想起她以前的故事。 那是我們剛上初一時(shí)尖淘,我們分到一個(gè)班奕锌,還是同位。她大大的眼睛村生,瓜子臉惊暴,皮膚有點(diǎn)微...
    紫色人生閱讀 311評(píng)論 1 2
  • 早上起來(lái)收拾完行李,整理皮包時(shí)烂斋,沒有發(fā)現(xiàn)這幾天內(nèi)訓(xùn)的筆記本屹逛,突然冒了一身冷汗,心想著:完了汛骂,那么寶貴的資料怎么能丟...
    吳秀芳閱讀 1,190評(píng)論 0 3