Android-线程
2020-08-24 本文已影响0人
有腹肌的豌豆Z
什么是线程?
- 线程指的是进程中的一个控制单元,也就是进程中的每个单元任务,一个进程中可以有多个线程同时并发运行。
- 线程的执行是通过CPU调度器来决定的,程序员无法控制。
- 线程是进程的基本组成单元,故也把线程称作进程元,或者轻型进程。
- 对于线程来说:堆内存空间是共享的,栈内存空间是独立的;线程消耗的资源比进程要小得多,且线程之间是可以相互通信的。
线程的状态/生命周期
public enum State {
/**
* 尚未启动的线程的线程状态。 刚创建出来的线程 new Thread()
*/
NEW,
/**
* (可运行/运行状态,等待CPU的调度)(要注意:即使是正在运行的线程,状态也是Runnable,而不是Running)
*/
RUNNABLE,
/**
* 等待监视器锁而被阻塞的线程的线程状态。运行被synchronized标记的代码且未获取到同步监视器。
* 阻塞状态
*/
BLOCKED,
/**
* 等待指定时间time threadA中调用threadB.join(time)。
* obj.wait(time)
* sleep(time)。
*/
TIMED_WAITING,
/**
* 线程终止,线程执行完成。
*/
TERMINATED;
}
停止线程
有时候我们可能需要强制中断 run() 方法的执行,怎么办呢?是使用 stop() 方法还是 interrupt() 方法呢?正确的姿势是调用 interrupt() 方法
- stop() 方法会真的杀死线程,不给线程一点儿喘息的机会,如果被杀死的线程持有 synchronized 隐式锁,那就再也不会释放掉这个锁了,接下来的线程也就没办法获得 synchronized 隐式锁,是不是特别危险?同样 suspend() 和 resume() 这两个方法也是不建议使用。废弃了。
- interrupt() 方法相比于 stop() 方法就温柔很多,它只是通知线程后续的操作可以不用去执行了,线程可以选择执行现在就不执行,当然也可以选择再执行一段时间后再停止,或者我就不听你的,非要执行完,都没关系, interrupt() 只是通知一下你而已。就比如你要做火车去一个地方,突然通知你这个火车晚点了,你可以选择无视这个通知继续等待,或者选择另外一趟高铁,但是不管你做什么,和火车站都没啥关系,它通知的责任尽到了。
线程状态函数
wait()
- 使一个线程处于等待状态,并且释放所有持有对象的lock锁,直到notify()/notifyAll()被唤醒后放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)。
sleep()
- 使一个线程处于睡眠状态,是一个静态方法,调用此方法要捕捉Interrupted异常,醒来后进入runnable状态,等待JVM调度。
notify()
- 使一个等待状态的线程唤醒,注意并不能确切唤醒等待状态线程,是由JVM决定且不按优先级。
allnotify()
- 使所有等待状态的线程唤醒,注意并不是给所有线程上锁,而是让它们竞争。
join()
- 使一个线程中断,IO完成会回到Runnable状态,等待JVM的调度。
Synchronized()
- 使Running状态的线程加同步锁使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。
Synchronized 同步
- 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
- 补充: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。
1、方法同步。
- 给方法增加synchronized修饰符就可以成为同步方法,可以是静态方法、非静态方法,但不能是抽象方法、接口方法。
- 线程在执行同步方法时是具有排它性的。
- 当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出,从而导致它释放了该对象的同步锁之后。
- 在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。
2、块同步。
- 同步块是通过锁定一个指定的对象,来对块中的代码进行同步;同步方法和同步块之间的相互制约只限于同一个对象之间,静态同步方法只受它所属类的其它静态同步方法的制约,而跟这个类的实例没有关系。
- 如果一个对象既有同步方法,又有同步块,那么当其中任意一个同步方法或者同步块被某个线程执行时,这个对象就被锁定了,其他线程无法在此时访问这个对象的同步方法,也不能执行同步块。