Java多线程并发编程问答-No8

22 阅读3分钟

一.Java中用到的线程调度算法是什么?

抢占式。

一个线程用完CPU指挥,操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。

二.什么是线程调度器和时间分片?

线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。

时间分片是指将可用的CPU时间分片给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。

三.什么是自旋?

很多synchronized里面的代码只是一些很简单的代码,执行时间非常快,此时等待的线程都加锁可能是一种不太值得的操作,因为线程阻塞涉及到用户态和内核态切换的问题。既然synchronized里面的代码执行非常快,不妨让等待锁的线程不要被阻塞,而是在synchronized的边界做忙循环,这就是自旋。如果做了多次忙循环发现还是没有锁,再阻塞,这样可能是一种更好的策略。

四.Java Concurrency API中的lock接口是什么?对比同步它有什么优势?

lock接口比同步方法和同步块提供了更具体扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。

优势是:

1.可以是锁更公平

2.可以是线程在等待锁的时候响应中断

3.可以让线程尝试获取锁,并且无法获取锁的时候立即返回或等待一段时间

4.可以在不同的范围,以不同的顺序获取和释放锁。

五.单例模式的线程安全性

首先要说的是单例模式的线程安全意味着:某个类的实例在多线程环境下只会被创建一次出来。单例模式有很多种的写法:

1.饿汉式单例模式的写法:线程安全

2.懒汉式单例模式的写法:非线程安全

3.双检锁单例模式的写法:线程安全

六.线程类的构造方法、静态块是被哪个线程调用的?

这是一个非常刁钻和狡猾的问题。请记住:线程类的构造方法、静态块是被new这个线程类所在的线程调用的,而run方法里面的代码才是被线程自身所调用的。

七.同步方法和同步块哪个是更好的选择?

同步块,这意味着同步块之外的代码是异步执行的,这比同步整个方法更提升代码的效率。

同步的范围越小越好。

八.Java线程数过多会造成什么异常?

1.线程的生命周期开销非常搞

2.消耗过多的CPU资源

如果可运行的线程数量多余可用于处理器的数量,那么有线程将会被闲置。大量空闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量的线程在竞争CPU资源时还将产生其他性能的开销。

3.降低稳定性

JVM在可创建线程的数量上存在一个限制,这个现在值将随着平台的不同而不同,并且承受着多个因素制约,包括JVM的启动参数、Thread构造函数中请求栈的大小,以及底层操作系统对线程的限制等。如果破坏了这些限制,那么可能抛出OutOfMemoryError异常。