java并发面试题(九)

  1. 线程的sleep()方法和yield()方法让出CPU资源后,竞争的线程有什么区别?
    答:sleep()方法让出CPU资源后,不管优先级高低,其他线程都能得到运行的机会。而yield()方法让出CPU资源后,只有优先级和它相等或比它高的线程可以有机会运行。

  2. 线程类的构造方法、静态块是被哪个线程调用的?
    答:线程类的构造方法、静态块是被new这个线程类所在的线程所调用的,而run方法里面的代码才是被线程自身所调用的。

  3. 在Java中ExecutorService和Executor有什么区别?
    答:首先ExecutorService接口继承了Executor接口,是Executor的子接口。Executor接口提供了一个execute()方法,只接受Runnable类型参数,,没有返回值,而ExecutorService接口的submit()方法可以接收Runnable或者
    Callable类型的参数,能够通过返回一个Future对象来接收到任务的结果。相比起Executor接口只有一个方法,ExecutorService接口提供了很多用来管理线程池的方法,比如shutdown()和shutdownNow(),这两个方法都是用来关闭线程池的不同手段。

  4. 说说Executors类是做什么用的?
    答:Executors类提供工厂方法用来创建不同类型的线程池。

  5. 为什么Thread里面的大部分方法都是final的?
    答:方法被final修饰符修饰,意味着方法无法被重写。这是因为线程的很多方法都是由系统调用的,不能通过子类覆写去改变他们的行为。

  6. 什么是自旋锁?
    答:没有获得锁的线程一直循环着,观察着等待着锁的持有者是否释放了锁,这就是自旋锁。

  7. 说说自旋锁的优缺点?
    答:如果自旋锁已经被别的线程先持有了,自旋锁也不会让调用者进入休眠,而是会循环观察锁的持有者是否释放了锁。不会进入休眠,就少了线程的上下文切换等操作,效率自然会高于其他互斥锁。不过自旋锁会占用过多的CPU时间,要是不能很快的获取到锁,就会导致CPU效率下降。而如果在递归中试图获取自旋锁则会引起死锁,因为递归程序不能在持有自旋锁时调用它自己,也不能在递归调用时试图获得相同的自旋锁。所以自旋锁适用于锁被持有的时间不会过长并且锁的竞争也不激烈的情况。

  8. 什么是互斥锁?
    答:在同一时刻只能被拿到一次的锁都叫互斥锁。

  9. 什么是读写锁?
    答:读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者。允许多个线程作为读者,而作为写者的线程同一时间只能有一个,且如果有线程在做写操作,那么其他线程无论是读还是写都是不被允许的。这样的话,读写锁能在读频率更高的情况下有更好的并发性能,毕竟大家都是在读数据,数据又没变化,为何不能一起读。

  10. Thread.sleep(0)的作用是什么?
    答:由于Java采用抢占式的线程调度算法,所以可能出现一个线程常常能够获取到CPU控制权的情况,那其他线程获取到CPU控制权的机会就会减小,而为了平衡下CPU控制权,可以使用Thread.sleep(0)来手动触发一次操作系统分配CPU时间片的操作。

发布了218 篇原创文章 · 获赞 220 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_38106322/article/details/104569364