Java线程面试5问(1)

266 阅读3分钟

线程有哪些状态?

答:new(新生),Runnable(可运行),Blocked(被阻塞),Waiting(等待),Timed waiting(计时等待),Terminated(被终止)。

一下细分这些状态:

  • new:但使用new操作符创建一个新线程时,如new Thread(r),该线程还没有开始运行。

  • Runnable:一旦调用start方法,线程处于Runnable状态。一个可运行的线程可能正在运行也可能没有运行,这取决于操作系统给线程提供运行的时间。

  • 被阻塞线程和等待线程:当线程处于被阻塞或者等待状态时,它不运行任何代码且消耗最少的资源。直到线程调度器重新激活它。区分Blocked(被阻塞),Waiting(等待),Timed waiting(计时等待),细节是取决于它是如何达到非活动状态的。

    • Blocked:当一个线程试图获取一个内部的对象锁,而锁被其他线程持有,则该线程进入阻塞状态。
    • Waiting:当线程等待另一个线程通知调度器的一个条件时,它自己进入等待状态。在调用没有设置Timeout参数的Object.wait方法或没有设置Timeout参数的Thread.join方法,或者是等待java.util.concurrent库中的Lock或Condition时,就会出现这种状况。
    • Timed Waiting:导致线程进入计时等待状态。Thread.sleep()方法,设置了Timeout参数的Object.wait()方法或设置了Timeout参数的Thread.join()方法都会导致线程进入Timed Waiting状态。
  • 被终止:线程因为这些方法而被终止

    • 因为run方法正常退出而自然死亡
    • 因为一个没有捕获的异常终止了run方法而意外死亡

synchronized和volatile,ReetrantLock,CAS的区别?

  1. synchronized关键字保证了并发三大特性的原子性,可见性和有序性

  2. volatile关键字保证了可见性和有序性,但无法保证原子性。如果一个共享变量被volatile关键字修饰,那么如果一个线程修改了这个共享变量后,其他线程是立马可知的。volatile还能禁止指令重新排序。

  3. ReetrantLock重入锁可以保证原子性,可见性和有序性。除此以外,还是可重入的,同一个线程每进入一次,锁的计数器都自增1,只有等到锁的计数器为0时才能释放锁。

  4. CAS机制中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。

    加锁的本质是将并发转变为串行来实现的,势必会影响吞吐量。对于并发控制而言,锁是一种悲观策略,会阻塞线程执行。而无锁是一种乐观策略,无锁的策略采用一种CAS来鉴别线程池冲突,一旦检测到冲突,就一直尝试当前操作直到没有冲突为止。

    与锁相比,CAS会使程序比较负责,由于其卓越的性能优势,以及天生免疫死锁(根本就没有锁,当然也就不会有线程一直阻塞了)。

synchronized 修饰实例方法和修饰静态方法有啥不一样?

synchronized 修饰实例方法:java中的每一个对象都有一个内部锁,如果一个实例方法用synchronized关键字声明,那么对象的锁将保护整个方法。如果要调用该方法,线程必须获得内部的对象锁。

synchronized修饰静态方法:该方法被调用时,该方法将会获得相关的类对象的内部锁,即class对象的内部锁。此时,没有其他线程可以调用同一个类的这个或者任何其他的同步静态方法。

Java线程面试5问(2)