线程与线程池

如题所述

第1个回答  2022-07-26
1、线程的状态。5个。

2、实现线程的方法,及其区别。2种:Runnable、Thread(+2种:Callable、FutureTask)。

3、start()和run()的区别。

4、Thread.sleep()和Thread.yield()区别
yield,音标 /jild/。线程的礼让,该线程退回到就绪状态(然后所有的就绪的线程凭借优先级抢资源)。
sleep,线程的阻塞(当阻塞时间结束,线程转入就绪状态)。

5、wait和sleep的区别
1)wait是object的方法,sleep是thread的静态方法;
2)wait需要在synchronized范围内使用,否则抛错 Exception in thread "main" java.lang.IllegalMonitorStateException ,而sleep则不需要;
3)wait是对象监听器的线程的等待,当该对象wait时,当前线程进入等待,其notify方法是随机唤起一个(等待该对象监听器的)线程;sleep是当前线程的沉睡,该线程的对象锁还是持有的;
4)wait出让系统资源,进入线程池中等待;sleep不会出让锁。二者都会让出CPU。

5、用户线程(user Thread)和守护线程(daemon Thread)的区别。
1)守护线程的区别在于thread.setDaemon(true),设置了就是守护线程,且必须在start()之前设置。
2)守护线程依赖于用户线程,没有用户线程,守护线程不存在。即当用户线程运行完毕,此时不管守护线程是否运行或运行完毕,立即停止。

6、线程调用的两种方式:
1)直接使用start()方法(在主方法中显式迭代调用或者构造方法中,便于外部隐式调用);
2)使用Executor来调用(CachedThreadPool()或者FixedThreadPool())。
两种方法的区别是:Executor执行线程都是隐式的。而且在构造方法中调用start()方法对于多线程是不安全的,而Executor则不会。

7、停止一个运行中线程的方法:
1)interrupt方法;
2)使用退出标志;
3)stop,但不建议(J8废除,原因是可能导致数据不一致)。

关于stop方法,参考 https://blog.csdn.net/a158123/article/details/78776145

6、Executor调用线程的两种方式的区别:
newCachedThreadPool()会为每一个任务都分配线程;
newFixedThreadPool(long)会限定可使用的线程数量,在前面的任务执行完之后,会将空线程分配给其他的任务。

7、在并发时,一个任务不能依赖于另一个任务,因为任务的关闭顺序无法保证。解决:1.依赖于非任务对象(volatile变量)来解决。2.锁。

8、锁的方式:2种,synchronize和Lock。区别在于Lock更加细粒度,比如锁的尝试获取,锁的锁定时间。

9、线程池的状态:5个。
1.running
2.shutdown
3.stop
4.tidying(当workQueue为0时,进入该状态)
5.terminated

10、shutdown和stop的区别。
二者都有线程池停止之意,且都不接收新线程了。但shutdown会处理掉已接收和正在执行的线程,而stop会中断所有的已接收和正在执行的线程。

11、threadPoolExecutor的参数含义。
corePoolSize:核心线程数。即最小存活线程数。
maximunPoolSize:最大线程数。
keepAliveTime:当线程数大于核心线程是,线程的存活时间。
unit:keepAliveTime的单位。
workQueue:工作队列。在线程执行前,线程会放在此处。
threadFactory:线程创建工厂(有一个默认工厂)。
handler:拒绝策略。当多余的线程请求时,执行的策略。默认是拒绝策略。

ps:关于workQueue:当需要使用一个线程时,会先看核心线程有无空闲线程,若有,则直接使用,没有,则创建并放在队列中等待被使用;当线程用完时,也会放在队列中,等待一会,实在没人用且已达到核心数时,会消亡该线程。

newSingleThreadExecutor() 和 newFixedThreadPool() 都是用的LinkedBlockingQueue队列,而 newCachedThreadPool() 用的是SynchronousQueue队列。
在 newSingleThreadExecutor() 中,如果前一个线程出异常了,那么我就执行下一个线程,不会出现停止,而其他的线程池会导致停止。
在 newFixedThreadPool() 中keepAliveTime是0,在 newCachedThreadPool() 中keepAliveTime是60s。

12、线程的循环调用(如每隔5秒调用线程):
这是一个初始化后延迟1秒,每隔5秒执行任务(秒单位共享)。

这是一个初始化后延迟1毫秒,每隔5秒执行任务。默认单位为毫秒。

参考: Java多线程线程池(4)--线程池的五种状态 。
相似回答