GeekBand第八周笔记
2016-07-03 15:54
615 查看
一、线程是什么
线程,有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程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
代码如下:
多线程使用方法:
1.AsyncTask<>,异步处理适合一次性的任务。因使用次数较多,就不详述了。
2.Handler,灵活,但也不适合大数量任务。
3、ExecutorServie线程池,适合处理大量线程。
通过Executors的静态方法来创建,一般有三种:
1.单线程 :Executors.newSingleThreadExecutor();
2.固定数量线程 :Executors.newFixedThreadPool();
3.动态线程 :Executors.newCachedThreadPool();
4.定时线程:Executors.newScheduleThreadPool();
这里我们用固定几个线程来应用,使用方法是创建ExecutorService对象,然后执行submit(r)可以发起一个Runnable对象。用线程池来管理的好处是,可以保证系统稳定运行,适用与有大量线程,高工作量的情景下使用,假如要展示1000张图片如果创建1000个线程去加载,保证系统会死掉。用线程池就可以避免这个问题,可以用几个线程轮流执行,几个一组,执行完的线程不直接回收而是等待下次执行,这样对系统的开销就可以减小不少。
线程,有时被称为轻量级进程,是程序执行流的最小单元。一个标准的线程由线程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(); } } }); }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories