1.死锁是如何发生的?

当线程A独占锁a,尝试获取锁b,而线程B独占锁b,尝试获取锁a时,因为线程AB互相持有对方想要的锁,而陷入死锁。

2.造成死锁的四个条件

1.互斥:某种资源一次只允许一个进程访问,即该资源一旦分配给了某个进程,其他进程就无法访问了。直至该进程访问结束。

2.占有且等待:一个进程本身占有资源,还有资源没有得到满足,在等待其他进程释放该资源。

3.不可抢占资源:别人已经占有了某项资源,不能因为自己需要,就去抢占资源。

4.循环等待:存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。

以上四点都满足,必然会发生死锁,发生死锁的进程无法运行下去,持有的资源无法释放,这样会导致CPU吞吐量下降,计算机性能降低。

3.如何避免死锁:

在并发环境下,避免多个线程互相持有对方需要的独占锁,就可以避免死锁的发生。

2.CAS的介绍:

1.Unsafe

Unsafe是CAS的核心类,因为Java无法直接访问底层操作系统,但是可以通过本地(native)方法来访问。不过尽管如此,JVM还是开了一个后门,JDK中有一个Unsafe的类,它提供了硬件级别的原子操作。

2.CAS

CAS,设计并发算法常用的一种技术。java.util.concurrent包完全建立在CAS之上,当前处理器也支持CAS,可见CAS的重要性。

CAS也是通过Unsafe实现的,CAS可以进行硬件级别的操作,因此比一般的加锁效率要高一些。

3.CAS的缺点:

CAS看起来虽然很美,但是也无法涵盖并发情况下的所有场景,而且从语义上面来说还是不完美。因为它存在一个漏洞:比如一个变量C,初始检测的时候值是A,当赋值的时候检测的值还是A,那么能说明C从来没有被其他线程修改过吗,显然不能,如果在此期间,被其他线程改成B,之后在改成A呢。但是CAS会误认为值从来没有被修改过。这个漏洞被称为CAS操作的“ABA”问题。大部分情况ABA问题不会影响程序并发的正确性,如果需要解决ABA问题,使用互斥同步锁可能比原子类更有效。