通过CAS算法保证操作的可靠性,正确性。不断尝试修改值,最快失败,保证了结果的最终一致性。
一、synchronized与Lock的区别
1.首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
2.synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
3.synchronized会自动释放锁 (a线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁);
Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
4.用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
5.synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可)
6.Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。
二、公平锁与非公平锁的区别
1、公平锁:是指多个线程按照申请锁的顺序来获取锁,类似排队打饭,先来后到。
2、非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发的情况下,有可能会造成优先级反转或者饥饿现象。
公平锁:Threads acquire a fair lock in which they requested
公平锁:就是很公平,在并发坏境中.每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁.否则就会加入到等待队列中.以后会按照FIFO的规则从队列中取到自己。
非公平锁:a nonfair lock permis barging:threads requesting a lock can jump ahead of the queue of waiting threads if the lock
happens to be available when it is requested.
非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁那种方式。
三、ReentrantLock和synchronized是公平锁还是非公平锁?
1、Java ReentrantLock 而言,通过构造函数指定该锁是否为公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。源码如下
Lock lock = new ReentrantLock(true);
对于synchronized而言,也是一种非公平锁。
CPU饥饿与线程饥饿
线程无法得到锁资源;cpu饥饿:在多核cpu中,在有锁保护的共享数据访问模型中,一旦一个线程取得了锁,那么其他线程在进行锁操作时都必须等待。这样只有一个线程在运行,导致只有一个CPU核在运行,其他CPU核都处于饥饿状态。
什么是饥饿线程?
长期没有得到运行的线程(没抢到时间片),为什么抢不到时间片 因为线程的级别从0-31,级别越高,执行的越高 抢占的时间片的可能就越高。