java线程中synchronized和Lock区别及介绍

 更新时间:2023年06月05日 08:33:29   作者:javacn_site  
这篇文章主要为大家介绍了java线程中synchronized和Lock区别及介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

synchronized 介绍与使用

synchronized 和 Lock 都是 Java 中用于实现线程同步的机制,它们都可以保证线程安全。

synchronized 可用来修饰普通方法、静态方法和代码块,当一个线程访问一个被 synchronized 修饰的方法或者代码块时,会自动获取该对象的锁,其他线程将会被阻塞,直到该线程执行完毕并释放锁。这样就保证了多个线程对共享资源的操作的互斥性,从而避免了数据的不一致性和线程安全问题。

synchronized 基本使用如下:

public class SynchronizedDemo {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
    public synchronized int getCount() {
        return count;
    }
}

此时我们再使用多线程调用上面类的 increment 或 getCount 时,就不会出现线程安全问题了,如下代码所示:

public class SynchronizedDemoTest {
    public static void main(String[] args) {
        SynchronizedDemo demo = new SynchronizedDemo();
        Runnable r = () -> {
            for (int i = 0; i < 1000; i++) {
                demo.increment();
            }
        };
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Count: " + demo.getCount());
    }
}

Lock 介绍与使用

Lock 是一种线程同步的机制,它与 synchronized 相似,可以用于控制对共享资源的访问。相比于 synchronized,Lock 的特点在于更加灵活,支持更多的操作。

Lock 接口定义了以下方法:

  • lock():获取锁,如果锁已被其他线程占用,则阻塞当前线程。
  • tryLock():尝试获取锁,如果锁已被其他线程占用,则返回 false,否则返回 true。
  • tryLock(long timeout, TimeUnit unit):尝试获取锁,在指定的时间范围内获取到锁则返回 true,否则返回 false。
  • unlock():释放锁。

相比于 synchronized,Lock 的优点在于:

  • 粒度更细:synchronized 关键字只能对整个方法或代码块进行同步,而 Lock 可以对单个变量或对象进行同步。
  • 支持公平锁:synchronized 不支持公平锁,而 Lock 可以通过构造函数指定锁是否是公平锁。
  • 支持多个条件变量:Lock 可以创建多个条件变量,即多个等待队列。

Lock 的实现类有很多,比较常用的有 ReentrantLock 和 ReentrantReadWriteLock。

需要注意的是,使用 Lock 时需要手动获取和释放锁,否则会导致死锁等问题。因此,一般来说建议使用 try-finally 语句块来确保锁的正确释放。例如:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    public void increment() {
        // 加锁
        lock.lock();
        try {
            count++;
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
    public void decrement() {
        // 加锁
        lock.lock();
        try {
            count--;
        } finally {
            // 释放锁
            lock.unlock();
        }
    }
    public int getCount() {
        return count;
    }
}

synchronized VS Lock

synchronized 和 Lock 主要的区别有以下几个方面:

  • 锁的获取方式:synchronized 是隐式获取锁的,即在进入 synchronized 代码块或方法时自动获取锁,退出时自动释放锁;而 Lock 需要程序显式地获取锁和释放锁,即需要调用 lock() 方法获取锁,调用 unlock() 方法释放锁。
  • 锁的性质:synchronized 是可重入的互斥锁,即同一个线程可以多次获得同一把锁,而且锁的释放也只能由获得锁的线程来释放;Lock 可以是可重入的互斥锁,也可以是非可重入的互斥锁,还可以是读写锁。
  • 锁的粒度:synchronized 是以代码块和方法为单位进行加锁和解锁,而 Lock 可以精确地控制锁的范围,可以支持多个条件变量。
  • 性能:在低并发的情况下,synchronized 的性能优于 Lock,因为 Lock 需要显式地获取和释放锁,而 synchronized 是在 JVM 层面实现的;在高并发的情况下,Lock 的性能可能优于 synchronized,因为 Lock 可以更好地支持高并发和读写分离的场景。

总的来说,synchronized 的使用更加简单,但是在某些场景下会受到性能的限制;而 Lock 则更加灵活,可以更精确地控制锁的范围和条件变量,但是使用起来比较繁琐。需要根据具体的业务场景和性能需求来选择使用哪种锁机制。

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

相关文章

  • eclipse老是自动跳到console解决办法

    eclipse老是自动跳到console解决办法

    eclipse启动服务后,想看一些properties信息或者别的,但老是自动跳转到console页面,本文给大家介绍了解决办法,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03
  • 详解JAVA 七种创建单例的方法

    详解JAVA 七种创建单例的方法

    这篇文章主要介绍了详解JAVA 七种创建单例的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • IDEA 2020.1打开时闪退的问题及解决方法(完美解决方法)

    IDEA 2020.1打开时闪退的问题及解决方法(完美解决方法)

    这篇文章主要介绍了IDEA 2020.1打开时闪退问题及解决方法,本文给大家分享我的处理方案,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Spring事务中@Transactional注解不生效的原因分析与解决

    Spring事务中@Transactional注解不生效的原因分析与解决

    在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为什么事务不生效,并提供多种解决方案,希望对大家有所帮助
    2025-03-03
  • Java集合List的使用详细解析

    Java集合List的使用详细解析

    这篇文章主要介绍了Java集合List的使用详细解析,List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引,鉴于Java中数组用来存储数据的局限性,我们通常使用java.util.List替代数组,需要的朋友可以参考下
    2023-11-11
  • Java中实现分布式定时任务的方法

    Java中实现分布式定时任务的方法

    这篇文章主要介绍了Java中实现分布式定时任务,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Spring Boot中自动执行sql脚本的实现

    Spring Boot中自动执行sql脚本的实现

    这篇文章主要介绍了Spring Boot中自动执行sql脚本的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • mybatis实现增删改查_动力节点Java学院整理

    mybatis实现增删改查_动力节点Java学院整理

    本文通过实例代码给大家介绍了mybatis实现增删改查功能,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-09-09
  • Java多线程中断机制三种方法及示例

    Java多线程中断机制三种方法及示例

    这篇文章主要介绍了Java多线程中断机制三种方法及示例,向大家分享了这三种方法的介绍几代码示例,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • java控制台输出版多人聊天室

    java控制台输出版多人聊天室

    这篇文章主要为大家详细介绍了java控制台输出版多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09

最新评论