• 线程高频面试题整理


    一、线程的生命周期是怎么样的?

    线程的生命周期可以分为五个部分,如图所示:

    • 新生状态:在程序中用构造方法(new 操作符)创建一个新线程时,如new Thread(),该线程就是创建状态,此时已经有了相应的内容空间和其他资源,但是还没有执行
    • 就绪状态:新建线程对象后,调用该线程的start()方法,就可以启动线程,当线程启动时,线程就进入了“就绪状态”(Runnable)由于还没有分配CPU,线程将进入线程队列排队,等待分配CPU服务,表明此时线程已经具备了运行条件,当系统挑选一个等待执行的Thread对象后,他也就从等待执行进入到了运行状态并且会自动调用自己的run方法
    • 运行状态:当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态
    • 阻塞状态:一个正在执行的线程在某些特殊的情况下,如被人为挂起或者需要进行耗时的输入输出操作的时候,将让出cpu并暂时终止自己的执行进入阻塞状态,如果调用sleep()、suspend()、wait()等方法,线程都将进入阻塞状态阻塞状态消除后回到的就绪状态,而不是运行状态
    • 死亡状态:线程调用stop()方法,destory()方法或者run执行结束,就会进入死亡状态

     二、sleep()和wait()的区别

    sleep()和wait()相同点:

    1、wait()和sleep()方法都可以让线程暂时中止

    sleep()和wait()不同点:

    1、sleep()不会释放锁,wait()会释放锁

    2、sleep()是Thread类的静态方法,wait()是Object类方法

    3、sleep()用于让线程在一定时间内停止,wait()大多用于线程间的交互和通信

    4、sleep()会自动唤醒,wait()可以通过notify()或notifyAll()来唤醒wait的线程。

    三、什么是原子操作?

    原子操作是指一个不受其他操作影响的操作任务单元。原子操作是在多线程环境下避免数据不一致必须的手段。

    int++并不是一个原子操作,所以当一个线程读取它的值并加1时,另外一个线程有可能会读到之前的值,这就会引发错误。

    为了解决这个问题,必须保证增加操作是原子的,在JDK1.5之前我们可以使用同步技术来做到这一点。到JDK1.5,java.util.concurrent.atomic包提供了int和long类型的封装类,它们可以自动的保证对于他们的操作是原子的并且不需要使用同步。

    四、我们如何创建一个线程?

    有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类。

  • 相关阅读:
    redis探索之缓存一致性
    杰理语音芯片ic玩具芯片ic的介绍_AD14NAD15N全系列开发
    IDEA新建SpringBoot项目时启动编译报错:Error:java: 无效的源发行版: 17
    使用soapUI获取webservice接口的调用格式
    基础课-排列组合
    【好书推荐】你想要的编码规范都在这里 | 《代码整洁之道》
    docker安装postgresSQL和设置自定义数据目录
    MySQL,刷题之对多表查询,题+代码!!
    离线环境harbor 搭建及使用
    我把一个json格式的数据读到dataframe里面了 怎么解析出自己需要的字段呢?
  • 原文地址:https://blog.csdn.net/weixin_45295447/article/details/127686179