中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android開發實踐:以“專業”的態度處理多線程

發布時間:2020-05-10 18:15:50 來源:網絡 閱讀:1346 作者:Jhuster 欄目:移動開發

   剛開始學一門編程語言的時候,我總是會有一種困惑,怎樣讓自己的代碼看起來更“專業”?很多時候,我們可以照著教材實現一些基本的功能,比如用Socket發送/接收幾個字符,寫一個線程完成某個異步任務,但是在實際的項目中,往往不那么簡單,比如需要設計Socket通信協議,需要處理Socket的連接異常斷開,需要考慮在線程阻塞的情況下如何正常退出和釋放資源等等,關于這些“實戰經驗”,前面的文章也有所涉及,以后有空準備再開個專題跟大家分享探討一下,今天先簡單地說說怎樣更“專業”地在Android程序中處理多線程。


   下面假設實現一個簡單的定時任務,每秒鐘打印一條Log信息,看看實現這樣一個多線程程序,有哪些需要注意的地方,關鍵點都以注釋的形式添加到代碼中了。


package com.ticktick.testthread;
               
import android.util.Log;
                
public class PrintThread implements Runnable {
                     
    private Thread mThread;
    private boolean mIsThreadStarted = false;
    private volatile boolean mIsThreadExit = false; //關鍵1:定義一個volatile類型的條件變量,用于線程的退出
                 
    public void startPrintThread() { 
                     
        if( mIsThreadStarted ) {
            return;
        }
        mIsThreadExit = false;
        mThread = new Thread(this); //關鍵2:每次啟動都重新創建新的Thread對象,因為一個Thread只能被start一次
        mThread.start();     
        mIsThreadStarted = true;
                     
        Log.d("PrintThread", "Timer Started");
    }
                 
    public void stopPrintThread() {
                     
        if( !mIsThreadStarted ) {
            return;
        }
        mIsThreadExit = true; //關鍵3:通知線程退出循環
                     
        mThread.interrupt(); //關鍵4:調用interrupt,防止線程內部處于sleep或者wait等阻塞狀態
                             //不過注意,對于socket.accept這樣的阻塞,thread.interrupt是沒有辦法的,但可以用socket.close來喚醒                   
                     
        try {
            mThread.join(1000); //關鍵5:調用join,等待線程真正地完成退出,建議給出一個等待超時時間
        }
        catch (InterruptedException e) {     
            e.printStackTrace();
        }
                     
        mIsThreadStarted = false;
                     
        Log.d("PrintThread", "Thread Stopped");
    }
                 
    public boolean isThreadStarted() {
        return mIsThreadStarted;
    }
                 
    @Override
    public void run() {
                     
        Log.d("PrintThread", "Thread Run Enter !");
                     
        while( !mIsThreadExit ) {
                         
            Log.d("PrintThread", "Thread Arrived !");
                         
            try {
                Thread.sleep(1000); //關鍵6:線程循環中,建議使用sleep,讓其他線程可以競爭CPU,sleep(0)代表立即重新競爭一次CPU
            }
            catch (InterruptedException e) {         
                e.printStackTrace(); //這里可以直接跳出循環,也可以忽略它而再次檢查條件變量 mIsThreadExit          
            }        
        }
                     
        Log.d("PrintThread", "Thread Run Exit !");
    }
                 
}


   其實,不僅是Java線程,C/C++的多線程也應該注意這幾個關鍵點,這里再總結一下:


  (1)要定義一個volatile類型的條件變量,決定是否退出線程的死循環


  (2)線程循環中,最好有sleep延時函數,讓其他線程有機會競爭CPU


  (3)要停止線程執行,需要做三件事,1. 置位線程退出的條件變量;2. 通過類似interrupt或者socket.close 的調用,喚醒線程中的阻塞;3. 通過join函數,等待線程真正退出,然后再釋放其他相關資源


   曾經在項目中,沒有通過join等待線程退出,導致經常會在軟件退出的時候莫名其妙地crash,因此,現在格外注意這一點,而且習慣性在線程結束的地方打印出調試信息,以保證程序中開啟的所有線程都正常地銷毀了。


   關于線程的處理就分享到這里啦,希望對初學者有幫助,有任何疑問歡迎留言或者來信lujun.hust@gmail.com交流。


附件:http://down.51cto.com/data/2364424
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

丘北县| 收藏| 潜江市| 罗定市| 和政县| 竹北市| 阳城县| 安新县| 蕉岭县| 滦南县| 昭觉县| 博客| 开江县| 商都县| 沙湾县| 乾安县| 新兴县| 古蔺县| 林周县| 宝鸡市| 若羌县| 札达县| 永宁县| 仁布县| 丹棱县| 仁寿县| 福州市| 胶州市| 中阳县| 祥云县| 江都市| 平定县| 罗甸县| 金山区| 岳池县| 锦州市| 永宁县| 安义县| 房产| 逊克县| 呈贡县|