什么是线程通信?
线程通信是指两个线程或两个以上的线程有共享的数据,线程之间有动作交互
wait() 和 notify()的作用?
void wait():当前线程进入等待状态,直到另一个线程调用当前对象的notify/notifyAll进行唤醒
void notify():唤醒正在等待对象监视的单个线程
void notifyAll():唤醒正在等待对象监视的所有线程
wait() 和 sleep()的区别是什么?
1. wait必须在synchronized中使⽤,⽽sleep却不⽤
2.sleep是Thread的⽅法,⽽wait是Object的⽅法
3.sleep不释放锁,wait释放锁
4.sleep有明确的终⽌等待时间,⽽wait有可能⽆限期的等待下去
5.sleep和wait产⽣的线程状态是不同的,sleep 是TIMED_WAITING状态,⽽wait是WAITING状态
什么是死锁现象?如何避免死锁现象?
线程死锁是指多个进程或线程互相等待对方的资源,在得到新的资源之前不会释放自己的资源,这样就形成了循环等待
即多个线程同时争抢同一个锁资源,出现程序的假死现象
避免死锁:
1.锁资源不要嵌套使用
2.加锁顺序(按照线程顺序加锁)
3.加锁时限(根据时间判断synchronized)
4.死锁检测
什么是线程池?线程池的好处?
线程池是一个可以容纳多个线程的容器,其中的线程可以反复使用,省去了线程的频繁创建和销毁,以节省资源开销
好处:
a.降低资源消耗,减少了创建和销毁线程的次数,每个工作线程都可以重复被利用,可以执行多个任务
b.提高响应速度,当任务(task)到达时,任务可以不需要等到线程创建就可以立即执行
c.提高线程的可管理性,使用线程池可以对线程进行统一的分配和监控
Callable接口 和 Runnable接口的区别?
Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;
Callable接口中的call()方法是有返回值的,是一个Object,Callable接口创建线程的方式只能用在线程池中
volatile关键词 和 synchronized的区别?
volatile时线程同步的轻量级实现,性能比synchronized好
volatile只能修饰变量,synchronized能修饰方法、代码块
volatile能保证数据的可见性,不能保证数据的原子性;synchronized能保证数据的原子性,也能间接保证可见性
总的来说,volatile保证了可见性,synchronized保证了同步性
什么是原子性,如何保证 原子性?
原子性是指在一个操作是不可中断的,要么全部执行成功要么全部执行失败,在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程所干扰。
如何保证:
synchronized一定能保证原子性,因为被其修饰的某段代码,只能由一个线程执行,所以一定可以保证原子性
java.util.concurrent.atomic和原子性相关的包也可以解决原子性问题,原子类的原子性是通过volatile和CAS实现的
什么是CAS算法? ABA问题?
CAS算法:Compare And Swap
有3个操作数(内存值V,旧的值A,要修改的值B)
①.当旧的值A == 内存值V,此时就要修改成功,将V改为B
②.当旧的值A != 内存值V,此时修改失败,并重新获取现在的最新值,再重新比较.
(重新获取的动作称之为自旋)
ABA问题:
当执行campare and swap会出现失败的情况。例如,一个线程先读取共享内存数据值A,随后因某种原因,线程暂时挂起,同时另一个线程临时将共享内存数据值先改为B,随后又改回为A。随后挂起线程恢复,并通过CAS比较,最终比较结果将会无变化。这样会通过检查,这就是ABA问题。 在CAS比较前会读取原始数据,随后进行原子CAS操作。这个间隙之间由于并发操作,最终可能会带来问题。只靠CAS无法保证ABA问题,需要使用“原子引用”才能解决