公平锁和非公平锁
==公平锁:先等待的线程先获得锁,先到先得,不能插队
==非公平锁:能够线程插队的锁,根据一定策略来进行调度,可能时间片少的先调度,可以进行插队
1、线程死锁
(1)多个线程各自占有一些资源,并互相等待其它线程占用的资源,导致多个线程都在等待对象释放资源,同时进入阻塞状态
(2)产生死锁的四个必要条件
==互斥条件:一个资源每次只能被一个进程使用
==请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
==不剥夺条件:进程已获得的资源,在未使用完之前,不能强行进行剥夺
==循环等待条件:若干进程间形成一种头尾相接的循环等待资源的关系
(3)如果预防和避免线程死锁
==1、破坏请求与保持条件:一次性申请所有的资源
==2、破坏不剥夺条件:占用部分资源的线程进一步申请其它资源时,如果申请不到,可以主动释放它占用的资源
==3、破坏循环等待条件:靠按序申请资源来预防。按某一顺序申请资源,释放资源则反序释放。破坏循环等待条件。
2、锁Lock
(1)线程同步机制——通过显示定义同步锁对象实现同步。同步锁:Lock对象
(2)java.util.concurrent.locks.Lock接口:控制多个线程对共享资源进行访问
(3)锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问资源前应先获得Lock对象。
(4)ReentrantLock(可重入锁),拥有与synchronized相同的并发性和内存语义。在实现线程安全的控制中,比较常用,可以显式加锁、释放锁。
==ReentrantLock与synchronized的对比
=====都是可重入锁
=====synchronized依赖于JVM实现,非公平锁
=====ReentrantLock依赖于JDK层实现的(API)
lock.lock()加锁,lock.unlock()解锁(需要try\\finally语句块配合实现)
=====ReentrantLock比synchronized增加了一些高级功能
1、等待可中断 lock.lockInterruptibly():可以选择烦请等待去处理其它事情
2、可以指定公平锁和非公平锁,ReentrantLock默认是非公平锁
ReentrantLock(boolean fair)构造方法来选择是否公平
3、ReentrantLock类线程对象可以注册在指定的Condition中,进行有选择性的线程通知。
=====优先使用synchronized,除非要使用ReentrantLock高级功能。
(5)Lock与synchronized的对比
=====Lock是显式锁(需要手动加锁,解锁),synchronized是隐式锁,出了作用域就会自动释放
=====Lock只有代码块锁,synchronized有代码块锁(同步代码块)和方法锁(同步方法)
=====Lock锁的使用,JVM将花费较少的时间来调度线程,性能更好,并且有更好的扩展性(提供更多的子类)
=====优先使用顺序:Lock->同步代码块->同步方法
=====synchronized不能判断获取锁的状态,lock可以判断锁的状态
=====synchronized不可以中断,lock可以中断
来源:https://www.cnblogs.com/hexiayuliang666/p/16155072.html
本站部分图文来源于网络,如有侵权请联系删除。