Java 多线程Synchronized和Lock的区别

引言

在多线程中,为了使线程安全,我们经常会使用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的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java多线程程序中synchronized修饰方法的使用实例

    在Java 5以前,是用synchronized关键字来实现锁的功能. synchronized关键字可以作为方法的修饰符(同步方法),也可作用于函数内的语句(同步代码块). 掌握synchronized,关键是要掌握把那个东西作为锁.对于类的非静态方法(成员方法)而言,意味着要取得对象实例的锁:对于类的静态方法(类方法)而言,要取得类的Class对象的锁:对于同步代码块,要指定取得的是哪个对象的锁.同步非静态方法可以视为包含整个方法的synchronized(this) { - }代码块.  

  • Java多线程synchronized同步方法详解

    1.synchronized 方法与锁对象 线程锁的是对象. 1)A线程先持有 object 对象的 Lock 锁, B线程可以以异步的方式调用 object 对象中的非 synchronized 类型的方法 2)A线程先持有 object 对象的 Lock 锁, B线程如果在这时调用 object 对象中的 synchronized 类型的方法,则需要等待,也就是同步. 2.脏读(DirtyRead) 示例: public class DirtyReadTest { public static

  • Java多线程实现TCP网络Socket编程(C/S通信)

    开篇必知必会 在前一篇<基于TCP协议网络socket编程(java实现C/S通信)>,实际存在一个问题,如果服务器端在建立连接后发送多条信息给客户端,客户端是无法全部接收的,原因在于客户端为单线程,只接受了第一条信息,剩余信息阻塞等待下一次发送.所以,这造成了客户端无法处理消息队列,每次只接收并输出一条服务器信息,出现信息不同步问题. 本篇将解决这个问题,详细记录实现java多线程通信,目标是使客户端可以一次接收服务器发送的多条信息,避免阻塞.方法是将客户端接收信息功能独立为一个线程来完成,

  • Java创建多线程的几种方式实现

    1.继承Thread类,重写run()方法 //方式1 package cn.itcats.thread.Test1; public class Demo1 extends Thread{ //重写的是父类Thread的run() public void run() { System.out.println(getName()+"is running..."); } public static void main(String[] args) { Demo1 demo1 = new D

  • 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)

    synchronized 和 Reentrantlock 多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢?是仅仅增加了一种选择还是另有其因?本文为您一探究竟. // synchronized关键字用法示例 public synchronized void add(int t){// 同步方法 this.v += t; } public stati

  • Java synchronized关键字和Lock接口实现原理

    这篇文章主要介绍了Java synchronized关键字和Lock接口实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 引用 当开发过程中,我们遇到并发问题.怎么解决? 一种解决方式,简单粗暴:上锁.将千军万马都给拦下来,只允许一个人过独木桥.书面意思就是将并行的程序变成串行的程序.现实的锁有门锁.挂锁和抽屉锁等等.在Java中,我们的锁就是synchronized关键字和Lock接口. synchronized关键字 synchron

  • 深入Synchronized和java.util.concurrent.locks.Lock的区别详解

    主要相同点:Lock能完成Synchronized所实现的所有功能.主要不同点:Lock有比Synchronized更精确的线程予以和更好的性能.Synchronized会自动释放锁,但是Lock一定要求程序员手工释放,并且必须在finally从句中释放.synchronized 修饰方法时 表示同一个对象在不同的线程中 表现为同步队列如果实例化不同的对象 那么synchronized就不会出现同步效果了.1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被

  • java多线程之Future和FutureTask使用实例

    Executor框架使用Runnable 作为其基本的任务表示形式.Runnable是一种有局限性的抽象,然后可以写入日志,或者共享的数据结构,但是他不能返回一个值. 许多任务实际上都是存在延迟计算的:执行数据库查询,从网络上获取资源,或者某个复杂耗时的计算.对于这种任务,Callable是一个更好的抽象,他能返回一个值,并可能抛出一个异常.Future表示一个任务的周期,并提供了相应的方法来判断是否已经完成或者取消,以及获取任务的结果和取消任务. public interface Callab

  • java多线程之线程,进程和Synchronized概念初解

    一.进程与线程的概念 (1)在传统的操作系统中,程序并不能独立运行,作为资源分配和独立运行的基本单位都是进程. 在未配置 OS 的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完后,才允许另一个程序执行:在多道程序环境下,则允许多个程序并发执行.程序的这两种执行方式间有着显著的不同.也正是程序并发执行时的这种特征,才导致了在操作系统中引入进程的概念. 自从在 20 世纪 60 年代人们提出了进程的概念后,在 OS 中一直都是以进程作为能拥有资源和独立运行的基本单位的.直到 20 世纪 8

  • Java线程安全解决方案(synchronized,ReentrantLock,Atomic)

    线程安全解决方案 synchronized,ReentrantLock,Atomic 使用场景描述 在实际开发过程中如果服务量,请求频繁,就会经常碰见并发,这时候不做处理就会出现很多非法数据.这时候就需要解决线程安全的问题,这时候就可以使用java当中的锁机制.常用有java关键synchronized.可重入锁ReentrantLock,还有并发包下的Atomic 或者Concurrent的安全类型. synchronized使用场景: 在资源竞争不是很激烈的情况下,偶尔出现并发,需要同步的情

  • Java编程synchronized与lock的区别【推荐】

    前言 本文介绍了Java编程synchronized与lock的区别的相关内容,如果您对synchronized与lock不太了解,这两篇文章 或许是不错的选择: Java 同步锁(synchronized)详解及实例 Java多线程基础--Lock类 正文 从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题

随机推荐