Java八股文面试(1)

2023-06-11  本文已影响0人  Jycoding

1.为什么不推荐通过Executors直接创建线程池呢(https://blog.csdn.net/zzhongcy/article/details/130323412)

【强制】线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

说明:Executors各个方法的弊端:

1)    newFixedThreadPool和newSingleThreadExecutor:  主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM(内存溢出)。

2)    newCachedThreadPool和newScheduledThreadPool:  主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。

总结:

newFixedThreadPool()、newSingleThreadExecutor() 底层代码 中 LinkedBlockingQueue 没有设置容量大小,默认是 Integer.MAX_VALUE, 可以认为是无界的。线程池中 多余的线程会被缓存到 LinkedBlockingQueue中,最终内存撑爆。

Executors.newCachedThreadPool()

优缺点:

优点: 很灵活,弹性的线程池线程管理,用多少线程给多大的线程池,不用后及时回收,用则新建 ;

缺点: 从源码中可以看出,SynchronousQueue() 只能存一个队列,可以认为所有 放到 newCachedThreadPool() 中的线程,不会缓存到队列中,而是直接运行的, 由于最大线程数是 Integer.MAX_VALUE ,这个数量级可以认为是无限大了, 随着执行线程数量的增多 和 线程没有及时结束,最终会将内存撑爆。

总结:

newCachedThreadPool()、newScheduledThreadPool() 的 底层代码 中 的 最大线程数(maximumPoolSize) 是 Integer.MAX_VALUE,可以认为是无限大,如果线程池中,执行中的线程没有及时结束,并且不断地有线程加入并执行,最终会将内存撑爆。

创建线程 或 线程池时请指定有意义的线程名称,方便出错时回溯(这个不是重点)

2.线程池有哪几种状态?每种状态分别表示什么?(https://blog.csdn.net/wufaqidong1/article/details/123724222)

在 Java 中,线程池的状态线程的状态是完全不同的,线程有 6 种状态:NEW:初始化状态、RUNNABLE:可运行/运行状态、BLOCKED:阻塞状态、WAITING:无时限等待状态(超时等待)、TIMED_WAITING:有时限等待状态和 TERMINATED:终止状态(线程的状态通常有五种:创建、就绪、运行、阻塞、死亡)。而线程池的状态有以下 5 种:

RUNNING:运行状态,线程池创建好之后就会进入此状态,如果不手动调用关闭方法,那么线程池在整个程序运行期间都是此状态。

SHUTDOWN:关闭状态,不再接受新任务提交,但是会将已保存在任务队列中的任务处理完

STOP:停止状态,不再接受新任务提交,并且会中断当前正在执行的任务、放弃任务队列中已有的任务

TIDYING:整理状态,所有的任务都执行完毕后(也包括任务队列中的任务执行完),当前线程池中的活动线程数降为 0 时的状态。到此状态之后,会调用线程池的 terminated() 方法,此方法留给用户自己实现。

TERMINATED:销毁状态,当执行完线程池的 terminated() 方法之后就会变为此状态。

3.Sychronized和ReentrantLock有哪些不同点?(https://blog.csdn.net/qq_19667981/article/details/124652865)

①ReentrantLock显示地获得,释放锁,synchronized隐式获得释放锁

②ReentrantLock可响应中断,可轮回,synchronized是不可以响应中断

③ReentrantLock是API级别的,synchronized是JVM级别的

④ReentrantLock可以实现公平锁或非公平锁,synchronized仅可实现非公平锁

⑤ReentrantLock通过Condition可以绑定多个条件

⑥底层实现不一样,synchronized是同步阻塞,使用的是悲观并发策略,lock是同步非阻塞,采用的是乐观并发策略。

⑦Lock是一个接口,而synchronized是java中的关键字,synchronized是内置的语言实现

⑧synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象, 因此使用 Lock 时需要在 finally 块中释放锁。

上一篇 下一篇

猜你喜欢

热点阅读