线程相关记录

误区一:(线程阻塞)

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”。

你可能感兴趣的:(线程相关记录)