http://www.mamicode.com/info-detail-517008.html
1、进程的三种状态
- 就绪状态:进程获得除CPU以外的所有资源,只要获得处理机便可执行
- 执行状态:进程获得处理机,正在处理机上执行
- 阻塞状态:进程等待某种事件发生(如等待I/O完成),放弃处理机而处于阻塞状态
2、线程的概念、线程的基本状态
- 新建
new 创建了一个线程对象,分配了内存 - 等待
new之后,start()之前 - 就绪
star()之后,位于CPU的可运行线程池中,等待CPU调度 - 运行
获得CPU执行权,任何时刻只会有一个线程处于运行状态,只有就绪状态中的线程才有机会进入运行状态 - 阻塞
- 等待阻塞:运行的线程调用wait()方法,JVM把线程放入等待池中,只有收到notify()或者notifyAll()消息,才会进入就绪状态(可运行)
- 同步阻塞:运行的线程在获取对象的同步锁时,该同步锁被其他线程占用,JVM会把这个线程放入锁池
- 其他阻塞:运行的线程调用sleep()方法,或者发出I/O请求,当sleep()超时或者I/O完成,线程就重新进入就绪状态
- 死亡
执行完run()
3、创建线程的三种方式
参考资料:[http://blog.csdn.net/longshengguoji/article/details/41126119]
- 继承Thread类,重写run
- 实现Runable接口,实现run,实现类的实例作为Thread类的参数传入
- 通过Callable接口和Future接口
- 创建Callable实现类,实现call方法
- 创建该实现类的对象,并用FutureTask类来包装该对象
- FutureTask对象作为Thread的参数 创建线程
- 调用FutureTask的get()获得子线程执行后的返回值
对比:
采用实现Runnable、Callable接口的方式创见多线程时,优势是:
线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。
在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
劣势是:
编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
使用继承Thread类的方式创建多线程时优势是:
编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。
劣势是:
线程类已经继承了Thread类,所以不能再继承其他父类
4、线程阻塞
- sleep()
是线程在指定时间内阻塞,指定时间一过重新进入就绪状态 - wait()和notify()
- wait(xxx) 当对应的notify()被调用或者超出指定时间,线程就会进入就绪状态
- wait() 只有当对应的notify()被调用 才会进入就绪状态
- suspend()和resume()
suspend()使线程进入阻塞状态并且不会自动恢复。只有当对应的resume()被调用才会进入就绪状态 - yield()
使线程放弃当前获得的CPU时间,但是不进入阻塞,线程任处于就绪状态,随时可以再获得CPU执行
- sleep()和wait区别
- sleep():Thread中;线程暂停执行指定时间,到时自动进入可运行状态,不会释放对象锁
- wait():Object中;线程释放对象锁,进入次对象的等待锁定池,只有针对次对象notify或notifyall,线程才会进入可运行状态