线程从创建到结束,分了很多状态以便管理。.
线程状态分为创建,运行,等待,超时等待和阻塞和结束五个状态.
- 创建:这个状态是线程刚刚创建,只是在堆内存中分配了空间.
- 运行:这是的线程已经执行了start()方法,等待获取cpu的运行权限,这里把运行状态和就绪状态合成了一个
- 等待:调用 wait() 或者是join()(join方法也是调用wait方法)
- 超时等待:给等待方法设置最长等待时间,
- 阻塞:没有获取到synchronized锁
- 结束:线程结束,这个结束可能是正常的结束,或者异常结束
- 创建的线程调用start进入就绪状态
- 就绪状态的线程获取时间片,得到cpu,获得线程的执行权
- 运行线程的时间片结束,线程还没有执行完进入就绪,或者调用yeid方法放弃本次cpu占用权
- 运行线程调用了**wait()**方法,或者join()方法,或者是LockSupport.park()方法,进入等待状态,进入等待队列。
- 运行线程调用wait(millis),jion(millis),Thread.sleep(millis),或者是LockSupport工具类的方法进入等待超时状态,进入等待队列
- 执行线程调用**notify(),notifyAll(),或者是LockSupport.unpark()唤醒等待线程;或者超时线程时间到了,进入就绪状态,进入同步队列。
- 遇到synchronized关键字,并且没有获取到锁,进入阻塞状态
- 线程执行完毕线程声明周期结束,或者遇到异常提前结束
需要注意的是
- 类似wait() 和 notify(), notifyAll() 属于等待通知机制,线程阻塞就是运用了该机制。
- 调用了wait()方法,会释放当前锁,并且在调用wait()方法前必须获取锁,同样,在调用condition.await()之前必须获取锁
- Thread.sleep()方法,不会释放锁,线程会进行阻塞,当睡眠时间结束,继续执行
- jion()方法是,挂起当前执行的线程,去执行别的线程,当别的线程执行完毕会继续执行自己,join()方法可以调节线程顺序,同样可以该作用的是,CountDownLatch 和 cycleBarrar类
- LockSupport类实现锁的await() 和 single()等方法
- 线程在创建的时候会继承父线程的属性区创建,所以很多属性需要修改的话需要自己set进去,对于设置守护线程需要在线程开启之前设置好,对线程名称的设置,利用volitale关键字,set方法用了synchronized修饰,确保线程的安全,可见;可以对线程设置优先级,该优先级从1到10级,但是优先级只是获取时间片的几率大,并不是优先级高一定获取,而且,系统对优先级的支持不一样,有的可能不支持
阻塞唤醒后的线程并不是直接进入运行状态,而是进入等待栈中,等着拿到cpu的执行权限.那么从就绪到运行态,需要做什么呢?
java采用了抢占式的线程调度,执行时会让优先级高的线程先执行,如果优先级相同,那就会随机执行一个.
当向调换线程的执行顺序的时候,需要调整优先级,或者让当前线程睡眠,或者直接调用其他线程,再或者调用Thread.yield()方法,放弃他的cpu使用.