Java 多线程Synchronized和Lock的区别

 更新时间:2021年01月04日 09:19:37   作者:zsq_fengchen  
这篇文章主要介绍了Java 多线程Synchronized和Lock的区别,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下

引言

  在多线程中,为了使线程安全,我们经常会使用synchronized和Lock进行代码同步和加锁,但是具体两者有什么区别,什么场景下适合用什么可能还不大清楚,主要的区别大致如下:

区别

    1、synchronized是java关键字,而Lock是java中的一个接口

    2、synchronized会自动释放锁,而Lock必须手动释放锁

    3、synchronized是不可中断的,Lock可以中断也可以不中断

    4、通过Lock可以知道线程有没有拿到锁,而synchronized不能

    5、synchronized能锁住方法和代码块,而Lock只能锁住代码块

    6、Lock可以使用读锁提高多线程读效率

    7、synchronized是非公平锁,ReentranLock可以控制是否公平锁

从Lock接口中我们可以看到主要有5个方法,这些方法的功能从注释中可以看出:

lock():获取锁,如果锁被暂用则一直等待
unlock():释放锁
tryLock(): 注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true
tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间
lockInterruptibly():用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事   通过 以上的解释,大致可以解释在上个部分中“锁类型(lockInterruptibly())”,“锁状态(tryLock())”等问题,还有就是前面子所获取的过程我所写的“大致就是可以尝试获得锁,线程可以不会一直等待”用了“可以”的原因。

lock():

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

  private void method(Thread thread) {
    lock.lock();
    try {
      System.out.println(thread.getName() + " has gotten the lock!");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.println(thread.getName() + " has unlocked the lock!");
      lock.unlock();
    }
  }

  public static void main(String[] args) {
    final LockTest test = new LockTest();

    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t1");
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t2");
    t1.start();
    t2.start();
  }

}

运行结果:

t1 has gotten the lock!
t1 has unlocked the lock!
t2 has gotten the lock!
t2 has unlocked the lock!

tryLock():

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

  private void method(Thread thread) {

    if (lock.tryLock()) {
      lock.lock();
      try {
        System.out.println(thread.getName() + " has gotten the lock!");
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        System.out.println(thread.getName() + " has unlocked the lock!");
        lock.unlock();
      }
    } else {
      System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!");
    }
  }

  public static void main(String[] args) {
    LockTest test = new LockTest();

    Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1");
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t2");
    t1.start();
    t2.start();
  }
}

运行结果:

t1 has gotten the lock!
t1 has unlocked the lock!
I'm t2. Someone has gotten the lock!

看到这里相信大家也都会使用如何使用Lock了吧,关于tryLock(long time, TimeUnit unit)和lockInterruptibly()不再赘述。前者主要存在一个等待时间,在测试代码中写入一个等待时间,后者主要是等待中断,会抛出一个中断异常,常用度不高,喜欢探究可以自己深入研究。

以上就是Java 多线程Synchronized和Lock的区别的详细内容,更多关于Java 多线程Synchronized和Lock的资料请关注脚本之家其它相关文章!

相关文章

  • Spring+Mybatis动态切换数据源的方法

    Spring+Mybatis动态切换数据源的方法

    这篇文章主要为大家详细介绍了Spring+Mybatis动态切换数据源的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Java语言实现快速幂取模算法详解

    Java语言实现快速幂取模算法详解

    这篇文章主要介绍了Java语言实现快速幂取模算法详解,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java变量常量声明和定义原理解析

    Java变量常量声明和定义原理解析

    这篇文章主要介绍了Java变量常量声明和定义原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java AES加密解密的简单实现方法

    Java AES加密解密的简单实现方法

    下面小编就为大家带来一篇Java AES加密解密的简单实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 在Spring中编写事务的介绍

    在Spring中编写事务的介绍

    今天小编就为大家分享一篇关于在Spring中编写事务的介绍,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • redis之基于SpringBoot实现Redis stream实时流事件处理方式

    redis之基于SpringBoot实现Redis stream实时流事件处理方式

    这篇文章主要介绍了redis之基于SpringBoot实现Redis stream实时流事件处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Springboot如何配置yml文件与映射到java类

    Springboot如何配置yml文件与映射到java类

    这篇文章主要介绍了Springboot如何配置yml文件与映射到java类问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java双向链表按照顺序添加节点的方法实例

    Java双向链表按照顺序添加节点的方法实例

    这篇文章主要给大家介绍了关于Java双向链表按照顺序添加节点的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • mybatis xml中特殊字符处理及特殊符号

    mybatis xml中特殊字符处理及特殊符号

    这篇文章主要介绍了mybatis xml中特殊字符处理及mybatis特殊符号处理技巧,mybatis特殊符号处理给大家介绍了两种写法,感兴趣的朋友一起看看吧
    2018-03-03
  • Java实战小技巧之数组与list互转

    Java实战小技巧之数组与list互转

    在Java中,经常遇到需要List与数组互相转换的场景,下面这篇文章主要给大家介绍了关于Java实战小技巧之数组与list互转的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-08-08

最新评论