Java并发基础(1)------Thread

创建Thread的方法:

  • 通过继承Thread类
  • 实现runnable接口
  • 使用线程池
  • 实现callable接口(call方法可以有返回值,可以抛出异常)

实现线程的常用的方法有以上几种,在选择实现线程的方法要注意以下几点:

  1. 如果要extend其他类的时候,建议使用除继承Thread类外方法,因为java不支持多继承
  2. 如果需要有返回值,可以实现callable接口
  3. 使用线程池创建线程可以避免因频繁的创建和销毁线程损耗系统的性能

Thread的生命周期

(1)生命周期

NEW (新建)

RUNNABLE(可运行)

RUNNING (运行)

BLOCKED (阻塞)

TERMINATED(中断)

(2)转化过程图示:

(3)注意点:

扫描二维码关注公众号,回复: 6390222 查看本文章
  • 使用 new 创建一个Thread 对象中,此时它并不处在执行状态,在没有执行Thread.start()方法前,只是一个普通的Thread对象,通过start进入RUNNABLE状态,这时候才会真正在JVM中创建了一个线程。

  • 线程对象进入RUNNABLE必须调用start,但是线程的运行与否,一样需要听任与CPU的调度。进入RUNNABLE状态后,线程只能意外终止或者进入RUNNING状态。

  • 线程对象进入RUNNING后,可能会有以下的可能

  • 线程对象进入BLOCKED后,可能会以下状态

  • 线程对象进入TERMINATED后,也会有几种情况(这是线程的最终状态了,线程不会切换到其他任何状态):

Thread常用方法

(1)sleep() 和 yield()区别

  • sleep会导致当前线程暂停指定的时间,没有CPU时间片的消耗
  • yield只是对CPU调度器的一个提示,如果CPU没有忽略这个提示,它会导致线程上下文的切换。
  • sleep会使线程短暂的block,会在给定的时间内释放CPU资源
  • yield会使running状态的Thread进入runnable状态
  • sleep机会百分百的完成了给定时间的休眠,而yield的提示并不能一定担保
  • 调用interruptsleep可以捕获到,而yield不会

(2)interrupt:线程的flag将会被设置,打断正在运行的状态。

(3)isInterrupted:线程状态的判断

(4)interrupted:是一个静态方法,会将当前的线程的状态设置为false,返回当前状态,第一次返回true,一直调用都只会返回false

Thread的源码分析

构造方法

阅读源码总结

  1. 线程的默认命名:线程会以"Thread-"作为一个自增数字为组合。

  2. 新创建的任何一个线程都会有一个父线程

    • 一个线程的创建一定是由另外一个线程完成的
    • 被创建的线程的父线程一定是创建他的线程,main函数所在的线程是有JVM创建的,即main线程,而main线程的父线程为System。
  3. 新建的线程如果没有显示指定线程组,则他会加入到父线程的线程组中。

  4. start()分析:模板设计模式:线程真正的逻辑实现在run方法中,我们需要通过重写Runnable接口对其进行构造,run方法是一个空的实现

  1. Thread对象创建后处于NEW状态,threadStatus这个内部属性为0,在start方法中会判断这个内部属性是否为0,如果不等于0会发生异常,所以说不能重复调用start方法或者在线程 结束后重新start。
  2. 线程启动后会被加入到一个线程组中,如果没有指定特定的线程组,会默认加入currentThread的线程组中。

猜你喜欢

转载自juejin.im/post/5cfe0376e51d45773e418a56