1.volatile可以保证线程安全吗?
2.volatile和sychronized比较?
3.什么是公平锁和非公平锁?
4.非公平锁吞吐量为什么比公平锁大?
5.Synchronized是公平锁吗?
6.ReentrantLock是怎么实现公平锁的?
7.介绍一下线程池的工作原理
8.线程池的参数有哪些?
9.线程池工作队列满了有哪些拒接策略?
10.有线程池参数设置的经验吗?
1.volatile可以保证线程安全吗?
volatile的两大作用是1.实现共享变量可见性,2.禁止指令重排。这两个功能还不足以保证线程安全。例如,对于复合操作i++,两个线程同时从内存中取i=0,同时i+1,再同时1写入i。这样i=1。结果是错的。
2.volatile和sychronized比较?
synchronized是一种内置锁,能够保证线程安全。确保同一时刻只有一个线程进入临界区。常用来修饰代码块或者方法。
volatile用来修饰变量,可以保证一个线程对于volatile变量的改变,其他拥有这个变量在工作内存的线程是及时可见的。同时,可以禁止指令重排,即通过设置读写屏障。
3.什么是公平锁和非公平锁?
公平锁是线程获取锁的先后顺序,按照申请锁的顺序。
非公平锁是多个一起抢,谁能抢到谁就直接占用锁,抢不到的就到队列的队尾等待。这可能造成一些线程饿死。
4.非公平锁吞吐量为什么比公平锁大?
公平锁:线程先休眠进入等待队列,然后按照队列顺序,从休眠态到运行态。从休眠态(waiting)到运行态都需要在用户态和内核态之间切换,而这个状态的转换是比较慢的。
非公平锁:线程先尝试通过CAS获取锁,获取失败才进入等待队列。相比于公平锁更加有效率。
5.Synchronized是公平锁吗?
Synchronized不属于公平锁。
Synchronized的实现原理是:
Synchronized是java提供的内置锁,这种使用者不可见的锁也被称为监控器锁。
在代码编译后,会在代码块上下加入monitorenter和monitorexit字节码指令。依赖于操作系统底层的互斥锁。即线程首先判断锁的status,如果status=0,通过CAS尝试获取锁,获取成功就修改状态和线程ID写入。如果status=1,那么会比较当前线程的ID和锁内记录的线程,如相同,可重入。计数器+1。当计数器值为0时,则锁释放。
6.ReentrantLock是怎么实现公平锁的?
ReentrantLock 支持两种锁:公平锁和非公平锁。何谓公平性,是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求上的绝对时间顺序,满足 FIFO。
公平锁盒非公平锁的主要实现关键点在于:protected final boolean tryAcquire(int acquires)
公平锁比非公平锁多判断一下,当前线程在等待队列里是否有前驱线程hasQueuedPredecessors。
7.介绍一下线程池的工作原理
线程池的最主要节省线程创建和销毁的性能开销。
首先判断当前线程数是否小于核心线程数,小于的话直接线程工厂创建线程并执行。不然就加入阻塞队列,如果阻塞队列满了,满了就看当前线程数与最大线程数的比较,小于的话就线程工厂创建现场并执行,就会按照一些丢弃的策略进行处理。
8.线程池的参数有哪些?
9.线程池工作队列满了有哪些拒接策略?
常用的四种拒绝策略包括:CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy,此外,还可以通过实现RejectedExecutionHandler接口来自定义拒绝策略。
CallerRunsPolicy:使用线程池调用者所在的线程去执行被拒绝的任务。
AbortPolicy:直接抛出任务被拒绝的异常。
DiscardPolicy:沉默地拒绝。
DiscardOldestPolicy:抛弃最老的,执行当前的。
10.有线程池参数设置的经验吗?
针对核心线程数。