每次学到的东西和运用的知识总是片面性的,没有一个很好的沉淀,近段时间有了空闲时间,所以对自身学到的点,进行一个简单的记录:
一、线程
1、定义
线程:程序中单独顺序的控制流,线程本身依靠程序进行运行,只能使用分配给程序的资源和环境。
2、作用
减少程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
3、实现
继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
super.run();
}
}
实现Runnable接口
public class MyRunnable implements Runnable {
@Override
public void run() {
}
}
4、状态
——创建状态:new 一个新线程对象
——就绪状态:调用start()方法,等待cpu进行调度
——运行状态:执行run()方法
——阻塞状态:sleep()/wait()暂时停止执行状态,可能把资源交给其他线程使用
——终止状态:线程销毁
5、线程属性
5.1、线程优先级
在Java程序设计语言中,每个线程都有一个优先级。默认情况下,一个线程继承他的父线程的优先级。使用setPriority(int newPriority)方法提高或者降低任何一个线程的优先级。
表示
// 譬如:
Thread.MIN_PRIORITY // 优先级1
Thread.NORM_PRIORITY // 默认优先级5
Thread.MAX_PRIORITY // 优先级10
注意:提高抢到cpu资源的可能性,但并不是一定能抢到cpu资源。
5.2、守护线程
定义:守护用户线程的线程,即在程序运行时为其他线程提供一种通用服务
常见:如垃圾回收线程
设置
//标识该线程为守护线程或用户线程。这一方法必须在线程启动之前调用。
setDaemon(boolean isDaemon)
5.3、非守护线程(用户线程)
主要包括:主线程&子线程
a. 主线程(UI线程)
定义:Android系统在程序启动时会自动启动一条主线程
作用:处理四大组件与用户进行交互的事情(如UI、界面交互相关)
注:因为用户随时会与界面发生交互,因此主线程任何时候都必须保持很高的响应速度,所以主线程不允许进行耗时操作,否则会出现ANR
b. 子线程(工作线程)
定义:手动创建的线程
作用:耗时的操作(网络请求、I/O操作等)
5.4 守护线程 与 非守护线程的区别
区别:虚拟机是否已退出:
当所有用户线程结束时,因为没有守护的必要,所以守护线程也会终止,虚拟机也同样退出
反过来,只要任何用户线程还在运行,守护线程就不会终止,虚拟机就不会退出
6、线程中的方法
sleep()和wait()
区别:
Java中的多线程是一种抢占式的机制 而不是分时机制。抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。
共同点:
(1)、它们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
(2)、wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep /join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
不同点:
(1)、Thread类的方法:sleep(),yield()等
Object的方法:wait()和notify()等
(2)、每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
(3)、wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
(4)、sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
二、多线程
1、定义
多个线程同时进行任务的执行,目的为了更好的使用CPU资源。
其实,计算机任何特定时刻只能执行一个任务;
多线程只是一种错觉:只是因为JVM快速调度资源来轮换线程,使得线程不断轮流执行,所以看起来好像在同时执行多个任务而已
2、作用
用来解决以下两种情况:
1、不阻塞UI线程:不在主线程中进行耗时操作。
2、不在非UI线程中更新UI组件。
3、使用场景
1、将耗时操作放在工作线程中进行。
2、将UI更新操作放在UI线程中进行。
4、实现方式
1、基础使用:
继承Thread
实现Runnable接口
Handler
2、复合使用
1、AsyncTask
2、HandlerThread
3、IntentService
3、高级使用
1、线程池 ThreadPool
5、同步与死锁
在大多数实际的多线程应用中,两个或者两个以上的线程需要共享对同一数据的存取,这种操作属于线程同步。
同步方法:用synchronized关键字进行修饰。
public synchronized void wAndroid(){
}
死锁:死锁就是两个或者两个以上的线程阻塞着,并且在等待其他死锁线程持有的锁。
三、进程
每一个应用程序启动时对应一个进程,一个进程包含一个或多个线程,一个进程至少包含一个线程。
四、总结
此篇文章中,对线程的基础知识进行了一个自我认知的一个统计,也是对自身的一个理解的记录,后期会一直进行完善。如果哪里理解的不对,欢迎指出。