GeekBand第八周笔记

一、线程是什么
线程,有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针,寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。
一个线程可以创建和撤销另一个线程,同一进程的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。

线程也有就绪,阻塞和运行三种基本状态。

  • 就绪状态就是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;

  • 运行状态是指线程占有处理机正在运行;

  • 阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都 至少有一个线程,若程序只有一个线程,那就是程序本身。
    这里写图片描述

    线程属性

1.轻型实体
线程中的实体基本上不拥有系统资源,只是有一点必不可少,能保证独立运行的资源。
线程的实体包括:程序,数据, TCB。线程是动态概念,它的动态性由线程控制块TCB(Thread Control Block)
TCB包括: a,线程状态 b,当线程不运行时,被保存的现场资源 c,一组执行堆栈 d,存放每个线程的局部变量主存区
e, 访问同一个进程中的主存和其它资源。
用于指示被执行指令序列的程序计数器,保留局部变量,少数状态参数和返回地址等的一组寄存器和堆栈。

2、 独立调度和分派的基本单位
在多线程中OS,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。由于线程很轻,故线程的切换非常迅速且开销小,在同一进程中。

3、可并发执行
在一个进程中的多个线程之间,可以并发执行,甚至允许一个进程中所有线程都能并发执行。同样,不同进程中的线程也能并发执行,充分利用和发挥了处理机与外围设备并行工作的能力。

4.共享进程资源
在同一进程中的各个线程,都可以共享该进程所拥有的资源,这表现:所有线程都具有相同的地址空间(进程的地址空间),这意味着,线程可以访问该地址空间的每一个虚地址。此外,还可以访问进程所拥有的已打开文件,定时器,信号量机等,由于同一个进程内线程共享内存和文件,所以线程之间互相通信不必调用内核。

二、多线程是什么?
多线程中,通常是一个进程中包括多个线程,每个线程都是作为利用CPU的基本单位,是花费最小开销的实体。

三、为什么要使用多线程?
效率更快,耗时操作不妨碍主线程进行其他任务,多项任务并行。

无论何时启动APP,所有的组件都会运行在一个单独的线程中(默认的)——叫做主线程。这个线程主要用于处理UI的操作并为视图组件和小部件分发事件等,因此主线程也被称作UI线程。

如果你在UI线程中运行一个耗时操作,那么UI就会被锁住,直到这个耗时操作结束。对于用户体验来说,这是非常糟糕的!这也就是为什么我们要理解Android上的多线程使用。

理解这些可以把一些复杂的工作移动到其它的线程中去执行。如果你在UI线程中运行一个耗时的任务,那么很有可能会发生ANR(应用无响应),这样用户就会很快地结束掉你的APP。

四、多线程的原理
这里写图片描述

这里写图片描述
这里写图片描述

五、Android中的多线程 。
 Android中的Main线程的事件处理不能太耗时,否则后续的事件无法在5秒内得到响应,就会弹出ANR对话框。所以就必须要使用多线程来处理耗时操作,避免出现卡顿和异常。
但是,Android是单线程模型,这意味着Android UI操作并不是线程安全的,所以UI操作必须在UI线程中执行。
所以如何沟通,就很重要。

当你新开线程去处理耗时任务,返回的结果如何在UI上更新:
在WorkerThread如何更新UI
Activity. runOnUIThread(Runnable);
View.post(Runnable)
View.postDelayed(Runnable)
Handler
代码如下:

//        UI线程
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text_view);

new Thread(new Runnable() {
  @Override
  public void run() {
    // 第一种 activity的方法
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
        mTextView.setText("我在其他线程。。。。");
        }
    });
    //  第二种
    mTextView.post(new Runnable() {
        @Override
        public void run() {
            mTextView.setText("我在其他线程。。。。");
        }
    });
    //    第三种
    mTextView.postDelayed(new Runnable() {
        @Override
        public void run() {
            mTextView.setText("我在其他线程。。。。");
        }
     },1000);
    //   第四种
    new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                mTextView.setText("我在其他线程。。。。");
            }
        });
        }
  });


}

多线程使用方法:
1.AsyncTask<>,异步处理适合一次性的任务。因使用次数较多,就不详述了。

2.Handler,灵活,但也不适合大数量任务。

 private DownloadHandler mHandler=new DownloadHandler(this);

private void loadImagesByThread(final String url,final int id){
    //通过Thread来new 出多个线程  
    new Thread(new Runnable(){  
          @Override  
          public void run() {  
                // TODO Auto-generated method stub  
               Log.e("当前线程:", ""+Thread.currentThread().getName());  
             Drawable drawable = null;  
                try {  
                   drawable = Drawable.createFromStream(new URL(url).openStream(), "image.gif");  
               } catch (MalformedURLException e) {  
                   // TODO Auto-generated catch block  
                  e.printStackTrace();  
               } catch (IOException e) {  
                   // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
              Message msg = mHandler.obtainMessage();  
               msg.what = 2012;  
               msg.arg1 = id;  
               msg.obj = drawable;  
               msg.sendToTarget();  

           }  

        }).start();  
    }

public static class DownloadHandler extends Handler{
        private WeakReference<MainActivity> mWeakReference;
        public DownloadHandler(MainActivity activity) {
            mWeakReference=new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
             MainActivity activity=mWeakReference.get();
            switch (msg.what){
                case 2012:
                    ((ImageView)activity.findViewById(msg.arg1))
                        .setImageDrawable((Drawable)msg.obj); 
                break;
            }
        }
    }

3、ExecutorServie线程池,适合处理大量线程。

通过Executors的静态方法来创建,一般有三种:

1.单线程 :Executors.newSingleThreadExecutor();

2.固定数量线程 :Executors.newFixedThreadPool();

3.动态线程 :Executors.newCachedThreadPool();

4.定时线程:Executors.newScheduleThreadPool();

这里我们用固定几个线程来应用,使用方法是创建ExecutorService对象,然后执行submit(r)可以发起一个Runnable对象。用线程池来管理的好处是,可以保证系统稳定运行,适用与有大量线程,高工作量的情景下使用,假如要展示1000张图片如果创建1000个线程去加载,保证系统会死掉。用线程池就可以避免这个问题,可以用几个线程轮流执行,几个一组,执行完的线程不直接回收而是等待下次执行,这样对系统的开销就可以减小不少。

 private ExecutorService service = Executors.newFixedThreadPool(5); 
 private void loadImagesByExecutors(final String url,final int id){  
       service.submit(new Runnable(){        
          @Override  
          public void run() {  
               // TODO Auto-generated method stub  
             Log.e("当前线程程:",""+Thread.currentThread().getName());  

             try {  
                 final Drawable drawable  = Drawable.createFromStream(new URL(url).openStream(), "image.gif");  
                mHandler.post(new Runnable(){  
                    @Override  
                    public void run() {//这将在主线程运行  
                          // TODO Auto-generated method stub  
                           ((ImageView)MainActivity.this.findViewById(id)).setImageDrawable(drawable);  
                        }  
                    });  

               } catch (MalformedURLException e) {  
                   // TODO Auto-generated catch block  
                   e.printStackTrace();  
               } catch (IOException e) {  
                    // TODO Auto-generated catch block  
                   e.printStackTrace();  
                }  

           }  

       });  

   }  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值