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

17 阅读2分钟

一.线程的调度策略

线程调度器选择优先级最高的线程运行,但是,如果发生以下情况,就会终止线程的运行:

1.线程体中调用了yield方法让出了对CPU的占用权力

2.线程体中调用了sleep方法使线程进入睡眠状态

3.线程由于IO操作收到阻塞

4.另外一个更高优先级线程出现

5.在支持时间片的系统中,该线程的时间片用完了

二.ConcurrentHashMap的并发度是什么?

ConcurrentHashMap的并发度就是segment的大小,默认是16,这就意味着最多同时可以有16条线程操作ConcurrentHashMap,这也是ConcurrentHashMap对Hashtable的最大优势。

三.Linux环境下如何查找哪个线程使用CPU最长

1.获取项目的PID,jps或者ps -ef | grep java

2.top -h -p pid

四.Java死锁以及如何避免

Java中的死锁是一种编程情况,其中两个或多个线程被永久阻塞,Java死锁情况出现至少两个线程和两个或更多资源。

Java发生死锁的根本原因是:在申请锁时发生了交叉闭环申请。

1.是多个线程涉及到多个锁,这些锁存在着交叉,所以可能会导致了一个锁依赖的闭环。

例如:线程在获得锁A并且没有释放的情况下去申请锁B,这时,另外一个线程已经获得了锁B,在释放锁B之前又要先获得锁A,因此闭环产生,陷入死锁循环。

2.默认的锁申请操作是阻塞的

所以要避免死锁,就要在一遇到多个对象锁交叉的情况,就要仔细审查这几个对象的类中的所有方法,是否存在着导致锁依赖的环路的可能性。

总之是进来避免在一个同步方法中调用其他对象的延时方法和同步方法。

五.不可变对象对多线程有什么帮助?

不可变对象保证了对象的内存可见性,对不可变对象的读取不需要进行额外的同步手段,提升了代码执行效率。

六.如果提交任务时,线程池队列已满,这时会发生什么?

1.如果使用的是无界队列LinkedBlockingQueue,也就是无界队列的话,没关系,继续添加任务到阻塞队列中等待执行,因为LinkedBlockingQueue可以近乎任务是一个无穷大的队列,可以无限存放任务。

2.如果使用的是有界队列比如ArrayBlockingQueue,任务首先被添加到ArrayBlockingQueue中,ArrayBlockingQueue满了,会根据maximumPoolSize的值增加线程数量,如果增加了线程数量还是处理不过来,ArrayBlockingQueue继续满,那么则会使用拒绝策略RejectedExecutionHandler处理慢了的任务,默认是AbortPolicy。