java多线程基础
生命周期
新建状态(NEW)
当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由jvm为其分配内存,并初始化其成员变量的值
就绪状态(RUNNABLE)
当线程对象调用了start()方法之后,该线程处于就绪状态。java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
运行状态(RUNNING)
如果处于就绪状态的线程获得了cpu,开始执行run()方法的线程执行体,则该线程处于运行状态。
阻塞状态(BLOCKED)
阻塞状态是指线程因为某种原因放弃了cpu使用权,也就是让出来cpu timeslice(cpu时间片),暂时停止运行。
直到线程进入可运行状态(runnable),才有机会再次获得cpu时间片转到运行状态(running)
阻塞的三种情况
- 等待阻塞(o.xait->等待队列):运行(running)的线程执行wait()方法后,jvm会把该线程放入等待队列(waitting queue)中
- 同步阻塞(lock->锁池):运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则jvm会把该线程放入池锁(lock pool)中
- 其它阻塞(sleep/join):运行(running)的线程执行sleep()或join()方法,或者发出了I/O请求时,jvm会把该线程设为阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O除了完毕时,线程重新转入可运行状态(runnable)
死亡状态(DEAD)
线程结束后就是死亡状态
- 正常结束:run()或者call()方法执行完成,线程正常结束。
- 异常结束:线程抛出一个未捕获的exception或error
- 调用stop:直接调用该线程的stop()方法来结束该线程。该方法非常容易导致死锁,不推荐使用
基本方法
方法 | 作用 |
---|---|
wait | 线程等待,调用该方法的线程进入waiting状态,只有等待另外线程的通知或被中断才会返回,需要注意的是调用wait方法后,会释放对象的锁。因此,wait方法一般用在同步方法或同步代码块中 |
sleep | 线程睡眠,sleep导致当前线程休眠,与wait方法不同的是sleep不会释放当前占有的锁,sleep会导致线程进入timed-wating状态,而wait会进入wating状态 |
yield | 线程让步,yield会使当前线程让出cpu时间片,与其它线程一起重新竞争cpu。一般情况下,优先级高的线程有更大的可能性竞争到cpu时间片,但这又不是绝对的,有的操作系统对线程优先级并不敏感 |
interrupt | 线程中断,中断一个线程,其本意是给这个线程一个通信信号,会影响这个线程内部的一个中断标识。这个线程本身并不会因此而改变状态 |
join | 等待其它线程终止,在当前线程中调用一个线程的join方法,则当前线程转为阻塞状态,等到另一个线程结束,当前线程再由阻塞状态变为就绪状态 |
notify | 线程唤醒,唤醒在此对象监视器上等待的单个线程,如果所有线程都在此对象上等待,则会选择其中一个线程 |
notifyAll | 唤醒在此监视器上等待的所有线程 |
isAlive | 判断一个线程释放存活 |
activeCount | 程序中活跃的线程数 |
enumerate | 枚举程序中的线程 |
currentThread | 得到当前线程 |
isDaemon | 一个线程是否为守护线程 |
setDaemon | 设置一个线程为守护线程 |
setName | 为线程设置一个名称 |
setPriority | 设置一个线程的优先级 |
getPriority | 获得一个线程的优先级 |