java中的synchronized关键字和lock接口

参考链接
Java锁–Lock实现原理(底层实现)
Lock与synchronized的区别和性能比较
Lock和synchronized的区别和使用

synchronized关键字和lock接口的区别

  1. lock是一个接口,而synchronized是java的一个关键字,synchronized是内置的语言实现。
  2. synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁;而lock发生异常时候,不会主动释放占有的锁,必须手动unlock来释放锁,可能引起死锁的发生,因此lock的unlock方法一般都是必须放在finally里面的。
  3. lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断。
  4. lock可以通过trylock来知道有没有获取锁,而synchronized不能;。
  5. Lock可以提高多个线程进行读操作的效率,可以通过readwritelock实现读写分离。

lock接口

lock的源码

public interface Lock {    
    //获取锁,如果锁被暂用则一直等待
    void lock();   
    //通过这种方式获取锁,会中断其他线程的锁等待。 
    void lockInterruptibly() throws InterruptedException;    
    //注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true
    boolean tryLock();   
    //比起tryLock()就是给了一个时间期限,保证等待参数时间
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;    
    //释放锁
    void unlock();    
    Condition newCondition();
}

lock的一般使用案例

package com.madman.base.concurr;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest{
    private Lock lock = new ReentrantLock();

    //需要参与同步的方法
    private void method(Thread thread) {
        lock.lock();
        try {
            System.out.println("线程名" + thread.getName() + "获得了锁");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("线程名" + thread.getName() + "释放了锁");
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        final LockTest lockTest = new LockTest();
        //线程1
        Thread t1 = new Thread(new Runnable(){

            @Override
            public void run() {
                lockTest.method(Thread.currentThread());
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable(){

            @Override
            public void run() {
                lockTest.method(Thread.currentThread());
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}

结果
运行结果发现是谁先获得锁谁就先执行,可以在中间添加线程添加睡眠来试一下。
这里使用的是lock.lock(),lock.tryLock()的使用和这个基本差不多,只不过lock.tryLock()有个返回值,你可以根据这个返回值进行特定判断。

线程名t1获得了锁
线程名t1释放了锁
线程名t2获得了锁
线程名t2释放了锁

lock接口的ReadWriteLock和ReentrantReadWriteLock

ReentrantReadWriteLock类实现了ReadWriteLock接口,ReadWriteLock接口还有两个方法

Lock readLock();
Lock writeLock();

关于ReadWriteLock和ReentrantReadWriteLock的使用参考
Lock和synchronized的区别和使用

猜你喜欢

转载自blog.csdn.net/u010316188/article/details/80284107