Android 多线程编程

一、进程和线程的概念
进程:一次程序的执行称为一个进程,每个 进程有独立的代码和数据空间,进程间切换的开销比较大,一个进程包含1—n个线程。进程是资源分享的最小单位。

线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小,线程是CPU调度的最小单位。

多进程:指操作系统能同时运行多个任务(程序)。

多线程:指同一个程序中有多个顺序流在执行,线程是进程内部单一控制序列流。

线程和进程一样包括:创建、就绪、运行、阻塞、销毁 五个状态:
1、新建状态(New):新创建了一个线程对象。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
(一)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。(wait会释放持有的锁)
(二)、同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
(三)、其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。(注意,sleep是不会释放持有的锁)
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期

二、多线程的优势
单线程的特点就是排队执行,也就是同步。而多线程能最大限度的利用CPU的空闲时间来处理其他的任务,系统的运行效率大大提升,使用多线程也就是在执行异步。

三、使用多线程
实现多线程编程的方式主要有两种,一种是继承Thread类,另一种是实现Runable接口。其实,使用继承Thread类的方式创建新线程时,最大的局限就是不支持多继承,因为Java语言的特点就是单根继承,所以为了支持多继承,完全可以实现Runnable接口,一边实现一边继承。但是这两种方式创建的线程在工作时的性质是一样的,没有本质的差别。

1.为什么要用多线程
提高用户体验,避免ANR;
异步处理事件(例如网络查看图片时,先显示占位图,等图片加载完成后,再显示图片);
多任务(例如一款音乐APP可以支持播放,歌词查看,列表查看等功能);

事件处理原则: 所有可能耗时的任务放在非主线程去处理;
Android主线程包括:UI绘制;控件事件处理;通俗来讲,在代码中on开头的,就是属于主线程的任务,例如onCreate()、onClick()等; 一般而言,在Activity的生命周期onCreate();onStart();onResume()的执行时间决定了APP打开的响应速度,所以不要把一些耗时操作放在里面处理,尽量放在其他线程;

Android多线程实现方式包括:

1、基础使用
继承Thread类
实现Runnable接口
Handler
2、复合使用
AsyncTask
HandlerThread
IntentService
3、高级使用
线程池(ThreadPool)

java多线程编程核心技术(一)–多线程技能
1、进程和线程的概念

1、进程:进程是操作系统的基础,是一次程序的执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,他是系统进行资源分配和调度的一个独立单位。

2、线程:线程可以理解为进程中独立运行的子任务,线程只能归属于一个进程并且它只能访问该进程所拥有的资源。

2、实现多线程编程的方式

1、继承Thread类,该类在源码实现上,也是实现了Runnable接口,使用该类最大的局限性就是java不支持多继承。

2、实现Runnable接口.

3、常用API

1、currentThread():返回代码段正在被哪个线程调用的信息。

2、isAlive():判断当前线程是否处于活动状态。

3、sleep():当前线程休眠。

4、getId():获取当前线程的唯一标识。

4、多线程方法

4.1、currentThread()方法

currentThread()方法可返回代码段正在被哪个线程调用的信息。

Thread.currentThread().getName()

4.2、isAlive()方法

方法isAlive()的功能是判断当前的线程是否处于活动状态。

thread.isAlive();

4.3、sleep()方法

方法sleep()的作用是在指定的毫秒数内让当前"正在执行的线程"休眠(暂停执行)。这个"正在执行的线程"是指this.currentThread()返回的线程。

Thread.sleep()

4.4、getId()方法

getId()方法的作用是取得线程的唯一标识。

thread.getId()

4、停止运行线程的方法

1、使用退出标志,是线程正常退出,也就是当run方法完成后线程退出。

2、使用stop方法强行终止线程,不推荐此方法,因为stop和suspend、resume方法都是作废过期的方法,使用将产生不可预期的结果。

3、使用interrupt方法中断线程。

5、suspend方法和resume方法

1、suspend():暂停线程

2、resume():恢复暂停线程的执行

缺点:这两个方法,使用不当,极易造成公共的同步方法被独占,使得其它线程无法访问。还会出现因为线程暂停而导致数据不同步的情况

6、yield():这个方法的作用是放弃当前的CPU资源,将它让给其它的任务去占用CPU执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。

7、线程的优先级

1、在操作系统中,线程可以划分优先级,优先级较高的线程得到的CPU资源较多,也就是CPU优先执行优先级较高的线程对象中任务。在java中,线程的优先级分为1~10这10个等级。如果超出,抛出异常

2、线程优先级的继承性:在java中,线程的优先级具有继承性,比如A线程启动B线程,则B线程跟A线程的优先级是一样的。

3、优先级具有规则性和随机性:高优先级的线程总是大部分先执行完,但不代表高优先级的线程总是每一次都先执行完。

8、守护线程:在java线程中,有两种线程,一种是用户线程。一种是守护线程,守护线程是一种特殊的线程,当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾会收线程

Java多线程编程核心技术(一)Java多线程技能
主题:

这套文章主要是把书上的内容自己消化一遍,把核心内容跟重点挑出来。读者可以用最少的时间了解这本书的内容。

   第一章主要讲解多线程的概念,使用方法,一些基本的api;每小节的内容不超过十句话的总结如下:

层级结构上是:

1.1进程跟多线程的概念;

1.进程可以理解为电脑的exe程序,线程可以理解为进程中单独运行的子任务;

2.多线程可以提高系统cpu使用率,运行效率得到提升

3.多线程是异步的,执行顺序并不是代码的顺序

1.2如何使用多线程;

1.继承Thread类,实现Runable接口;如MyThread extends Thread; Myrunalble implements Runable

2.Thread类本身也实现了runable接口

3.start方法通知“”线程规划器“已经准备就绪,等待调用run方法,直接调run的话就是事实启动不是异步的了。

4.Thread的构造函数可以传入Runable接口,如Thread a = new Thread(new Runable());

5.变量实例分为共享和不共享之分,共享变更可能因为线程同步的问题出现数据上的差异,要使用synchronized关键字;

6.printIn()方法中,虽然这个方法是同步的,但是i–的操作是在printIn()之前发生。所以有非线程安全问题的概率。

1.3currentThread方法

1.Thread.currentThread().getName();

2.this.getTime()

1.4isAlive方法

1.活动状态是指线程已经启动并且尚未终止,线程处于正在运行或者准备开始运行的状态,此时会认为线程是存活的。

2.Mythread.isAlive();

1.5sleep方法

1.让当前线程休眠(暂停执行)

1.6getID方法

1.获取线程的唯一标识

1.7停止线程

1.处理完任务之前停止正在做的操作。

2.使用stop可以立即停止,但是不赞成使用(不安全);更推荐使用Thread.interrupt;此方法不会终止一个正在运行的线程,要加上判断才能停止。

3.interrupt只是在线程中打了一个停止的标记。并不会真的停止。

4.this.interrupted();测试当前线程是否已经中断。会清除状态。this.isInterrupted();测试线程thread是否已经中断

5.推荐终止线程的方法。this.interrupted()。手动创建异常后面用异常捕获。

6.如果在sleep状态下停止线程,会进入异常

7.stop方法不推荐使用是因为线程停止可能会导致一些清理工作得不到完成,可能会锁定的对象进行了解锁,出现数据不一致的问题。

1.8暂停线程

1.可以使用suspend暂停线程,resume恢复线程执行。

2.如果加了sync关键字,暂停线程后没有恢复,可能导致公共资源无法访问。没加关键字,暂停之后可能出现数据不一致

1.9yield方法

1.放弃当前的cpu资源,让其他的任务去占用cpu;

2.Thread.yield();

1.10线程的优先级

1.设置线程可以使用setPriority(),在java中,线程分了1-10个等级。

2.优先级是可以继承的。如果是a线程启动的b线程,那b的线程与a的线程优先级一样的。

3.cpu会把资源让给优先级比较高的线程

4优先级有随机性,优先级高的不一定每一次都先执行完。

1.11守护线程

1.线程分两种,一种是用户线程,一种是守护线程。

2.守护线程守护一个非守护线程,当不存在非守护线程了,守护线程字段销毁

3。典型的守护线程如垃圾回收线程。

总结:

主要学习线程的api

参考:
https://www.cnblogs.com/jmcui/p/7486257.html
https://www.cnblogs.com/umgsai/p/5494561.html
https://blog.csdn.net/qq_41648631/article/details/103045252

猜你喜欢

转载自blog.csdn.net/weixin_44008788/article/details/107824279