線程相關記錄

誤區一:(線程阻塞)

private void button1_click() throws InterruptedException {
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setMessage("加載中...")
            .show();
    Thread.sleep(5000);
    button1.setText("加載完畢");
    dialog.dismiss();
}

????????以上代碼,很多人描述看到的效果是:點擊按鈕后,彈出一個對話框,顯示“加載中...”,5秒后按鈕顯示文字變成了“加載完畢”,對話框消失。
????????但是以上描述是錯誤的,你根本看不到對話框,你會發現事實上是這樣的:點擊按鈕后,按鈕沒有抬起來,5秒后,按鈕抬起來了,同時按鈕文字變成了“加載完畢”。
????????我們發現原來整個過程中,AlertDialog毫無存在感,根本也看不到它出現,原因是因為,這里發生了UI線程阻塞。當要show出dialog的時候,下一句是Thread.sleep(5000),這句話的意思是,當前的線程睡眠5秒,也就是UI線程,因為這句代碼沒有寫在子線程中,如果它寫在了子線程中,那么睡眠的就是子線程了,而非主線程。當睡眠完后,馬上修改按鈕的文字,再讓dialog消失,dialog的整個顯示到消失,排除掉睡眠時間,肉眼根本無法捕捉到。
????????如果我們真的要達到很多人描述的那種效果,我們需要這樣修改(且不說代碼嵌套層次和優化):

private void button1_click() throws InterruptedException {
    AlertDialog dialog = new AlertDialog.Builder(this)
            .setMessage("加載中...")
            .show();

    new Thread(new Runnable() {
        @Override
        public void run() {
            Thread.sleep(5000);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    button1.setText("加載完畢");
                    dialog.dismiss();
                }
            });
        }
    }).start();
}




誤區二:(cpu對線程的調度)

private void button1_click(View view) {
    final AlertDialog dialog = new AlertDialog.Builder(this)
            .setMessage("加載中...")
            .show();
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        button1.setText("加載完畢1");
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }).start();

    button1.postDelayed(new Runnable() {
        @Override
        public void run() {
            button1.setText("加載完畢2");
            dialog.dismiss();
        }
    },3000);
}

????????以上代碼,很多人描述看到的效果是:點擊按鈕后,彈出一個對話框,顯示“加載中…”,5秒后,按鈕文字變成了“加載完畢1”,又停了3秒后,按鈕問題變成了“加載完畢2”,對話框消失。
????????同樣,以上描述也是錯誤的。我們可以理解線程的開啟,就是一個任務塊的開啟,打開一個任務的開啟,并不需要花費cpu什么時間,同樣的,postDelayed也只是通知cpu,3秒后開啟一個任務,也是不需要花多少時間的,至于具體去處理這些任務的時候,那又是另一個層面的事情,不會影響當前的代碼執行順序,也就是說,整個代碼塊,我們可以理解為在UI線程中,只給cpu下達了三個命令:彈出一個對話框,開一個子線程執行一個任務,3秒后執行一個任務。
????????所以,我們看到的效果應該是:點擊按鈕后,彈出一個對話框,顯示“加載中…”,3秒后,按鈕問題變成了“加載完畢2”,對話框消失,又過了2秒后,按鈕文字變成了“加載完畢1”。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容