lock和synchronized

线程共有五个状态:
新建:调用start之前、
就绪:调用start之后。run之前、
开始:线程被设置为当前线程,开始执行run方法、
阻塞:线程被暂停、
死亡:线程结束

1.lock和synchronized区别
(1)synchronize是java的关键字,而lock是一个接口。
(2)synchronize和lock都作为锁,synchronize可以在线程synchronize方法完毕或堵塞的时候释放锁,而lock则需要在finally中手动释放锁,不然就有可能造成死锁的现象。
(3)lock可以做到多线程同时进行读操作。如果有一个线程占用读锁,另外的线程需要申请写操作都需要等待第一个线程释放锁。
如果有一个线程进行写操作的时候,第二个线程要进行读写操作都需要等待第一个线程释放锁。
(4)lock可以读取知道线程是否成功获取锁。synchronize不行。
(5)lock可以让等待的线程响应关闭,synchronize不行。


2.Lock简单使用
Lock是一个接口,里面有五个方法。 ReentrantLock是lock接口唯一的实现类
      
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();

lock()用于获取锁,unlock用户释放锁
tryLock()用于查看线程是否成功获取锁,若成功返回true,否则返回false
tryLock( long   time, TimeUnit unit)和tryLock()类似,但可以加入一个时间参数,若在指定时间内都没有返回true则返回false
lockInterruptibly()是lock类中获取锁的方法,如若线程1获取锁,线程2申请锁在等待过程中,可以使用thread2.interrupt()方法使线程2响应关闭
//注意,如果需要正确中断等待锁的线程,必须将获取锁放在try catch外面,然后将InterruptedException抛出

如何使用lock接口可以同时进行多线程读操作?
ReadWriteLock也是一个接口,其中定义了两个方法。
    Lock readLock();
     Lock writeLock();
获取读锁和获取写锁。也就是将文件的读写操作分开,从而使得可以有多线程进行读操作 ReentrantReadWriteLock实现了ReadWriteLock接口。(调用获取读锁方法rwl.readLock().lock();



3.锁的相关概念
1.可重入锁
synchronize和ReentrantLock()都是可重入锁,可重入性可以说就是锁的分配机制,基于线程的分配而不是基于调用方法的分配。比如在同一对象中有两个方法都加上了synchronize锁,在方法一取得锁的时候,在方法一内部调用方法二,如若synchronize不具备可重入性,那么在方法一调用方法二的时候,方法二需要再去申请锁,但是由于方法一已经取得了该锁,所以方法二永远都不可能申请到锁。
2.可中断锁
synchronize不是可中断锁,lock是可中断锁(使用 lockInterruptibly()方法)。
3.公平锁
公平锁即按照线程请求锁的顺序来分配锁,在一个线程释放锁的时候,等待时间最久的那个线程先获得锁。
synchronize为非公平锁。所以可能有一个线程永远都获取不到锁。
lock默认为非公平锁,但是可以在实例化的时候: ReentrantLock lock =  new   ReentrantLock( true );来配置为公平锁。
4.读写锁

猜你喜欢

转载自blog.csdn.net/qq_38439885/article/details/79872935