携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详情
线程的状态
线程有6个状态:
- 初始New:新创建的线程,还未执行 start() 方法
- 运行状态 Runable:Java线程中就绪和运行都成为 runable 状态,所以要么正在运行,要么正在等待操作系统分配资源
- 阻塞状态 Blocked:阻塞等待锁的线程状态,
- 等待状态 Waiting:等待状态,需要等待另一个线程执行某个特定动作。如 notify 或者中断
- 超时等待 Timed_Waiting:该等待是在超过设置的超时时间时进入该状态,如 Object.wait(long timeout) 和 Thread.join(long timeout) 设置超时时间
- 终止状态 terminated:当线程执行完成时就所有终止
线程的工作模式
- 创建线程,并执行线程要执行的业务方法;
- 调用线程的 start() 方法,线程就进入 Runable 状态,此时应该还是就绪状态;
- 如果执行业务方法中遇到 synchronized 同步代码块且其他线程也在使用此锁时,就会进入 Blocked 状态。其他线程的释放锁后就会继续进入 Runable 状态,此时就是运行状态;
- 当遇到 Object.wait() 或 Thread.Join() 方法时,就会进入 Waiting 状态。直到有其他的线程执行 notify 或 notifyAll 的方法时就会进入 runable 状态,运行状态;
- 如果 Object.wait(long timeout) 或 Thread.Join(long timeout) 带有超时时间,超过超时时间就会进入 Time_Waiting 状态,此时也是需要等待其他线程 notify 时才会进入 runable 状态,运行状态;
- 方法都执行完成后就终止 Terminated ,整个线程的流程就执行完成
start() 和 run() 区别
- start(), 是线程 Thread 自身的方法,并且使用 synchronized 来保证线程安全;start() 方法可以开启多线程;只能被调用一次
- run(), 是 Runnable 的抽象方法,必须由调用类重写此方法,重写的 run() 方法其实就是此线程要执行的业务方法;run() 方法只是一个普通的方法,可以进行多次调用。
线程常用方法
- join() 一个线程调用 other.join()时,当前线程就会waiting 然后让 other 线程执行,直到该线程结束或被time_waiting 时原线程才会继续执行。就是线程执行权交给其他线程。
- yield() 方法表示给线程调度器一个当前线程愿意出让 CPU 使用权的暗示,但是线程调度器可能会忽略这个暗示。一般工作中几乎找不到合适的应用场景,只要当一个线程不那么重要,又怕它占用了太多的 CPU 资源时,可以适当的调用一下 yield 方法。