首页 > 数据库 >关于锁的使用,千万不要踩这个坑!(附带Synchronized详解和ZooKeeper、Redis等分布式锁详解)

关于锁的使用,千万不要踩这个坑!(附带Synchronized详解和ZooKeeper、Redis等分布式锁详解)

时间:2024-06-24 11:00:03浏览次数:32  
标签:Synchronized synchronized ZooKeeper Redis 关键字 详解 分布式系统 分布式

1、分布式锁

在分布式系统中,我们经常会使用各种锁来保证数据的一致性和并发安全。一些常见的分布式锁实现包括:

  1. 基于ZooKeeper的分布式锁:使用ZooKeeper节点的特性来实现分布式锁。

  2. 基于Redis的分布式锁:利用Redis的原子性操作和过期时间特性来实现分布式锁。

  3. Redlock算法:由Redis官方提出的一种分布式锁算法,基于多个Redis实例的协作实现分布式锁。

  4. 基于数据库的分布式锁:利用数据库的事务特性和唯一性约束来实现分布式锁。

  5. 基于Java库的分布式锁:如Curator框架中提供的分布式锁实现等。

2、synchronized在分布式中的并发问题以及ZooKeeper和Redis介绍

在分布式系统中,synchronized关键字通常不会直接起作用,因为Synchronized关键字只能同步单个JVM中的线程。在分布式系统中,需要使用分布式锁来实现跨多个节点的线程同步和协调。

让我们了解一下什么是分布式锁。分布式锁是一种用于控制对共享资源访问的机制,它允许在分布式环境中协调多个节点上的并发操作。在传统的单机应用中,我们可以通过synchronized关键字来保证同一时间只有一个线程可以访问共享资源。然而,在分布式系统中,由于存在多个独立的节点,我们需要一种机制来确保这些节点之间的一致性。

为了实现这一点,我们可以使用基于ZooKeeper或Redis等分布式存储系统的分布式锁。这些系统提供了一种可靠的方式来管理分布式锁,并且支持高可用性和容错性。

ZooKeeper

ZooKeeper是一个开源的分布式协调服务,它提供了许多强大的功能,包括分布式锁。在ZooKeeper中,每个锁都对应一个路径,当一个节点获取到这个路径的锁时,其他节点将无法获取该锁,直到第一个节点释放锁为止。

以下是使用ZooKeeper实现分布式锁的一个简单示例:

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

public class DistributedLockExample {
    private static final String ZK_HOSTS = "localhost:2181";
    private static final String LOCK_PATH = "/my-lock";

    public static void main(String[] args) throws Exception {
        ZooKeeper zk = new ZooKeeper(ZK_HOSTS, 3000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("Received event: " + event);
            }
        });

        try {
            // Acquire the lock
            zk.create(LOCK_PATH, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

            // Do some work here...

            // Release the lock
            zk.delete(LOCK_PATH, -1);
        } finally {
            zk.close();
        }
    }
}

在这个示例中,我们首先创建了一个ZooKeeper实例,并设置了一个锁的路径。然后,我们尝试获取这个锁。如果成功获取,则表示没有其他节点持有这个锁,我们就可以执行一些工作。最后,我们释放锁并关闭ZooKeeper连接。

Redis

Redis也是一个流行的分布式存储系统,它也支持分布式锁。与ZooKeeper不同的是,Redis的分布式锁是基于内存的,这意味着锁的生命周期取决于服务器重启。但是,对于大多数应用程序来说,这已经足够了。

以下是使用Redis实现分布式锁的一个简单示例:

import redis.clients.jedis.Jedis;

public class DistributedLockExample {
    private static final String REDIS_HOST = "localhost";
    private static final int REDIS_PORT = 6379;
    private static final String LOCK_KEY = "my-lock";

    public static void main(String[] args) throws Exception {
        Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT);

        try {
            // Acquire the lock
            if (!jedis.setnx(LOCK_KEY, "1")) {
                System.out.println("Failed to acquire lock");
                return;
            }

            // Do some work here...

            // Release the lock
            jedis.del(LOCK_KEY);
        } finally {
            jedis.close();
        }
    }
}

在这个示例中,我们首先创建了一个Jedis实例,并设置了一个锁的键。然后,我们尝试获取这个锁。如果成功获取,则表示没有其他节点持有这个锁,我们就可以执行一些工作。最后,我们释放锁并关闭Jedis连接。

总结起来,无论是使用ZooKeeper还是Redis,分布式锁都是实现分布式系统中线程同步和协调的重要工具。通过使用这些工具,我们可以确保在分布式环境中正确地处理共享资源,并避免潜在的数据竞争问题。

3、 synchronized详解

当然,为了更好地理解分布式锁和synchronized关键字之间的关系,我们可以进一步探讨synchronized关键字及其在分布式环境下的使用场景和注意事项。

synchronized关键字

synchronized关键字用于同步方法或代码块,以确保同一时间只有一个线程可以访问共享资源。这是Java中最基本的同步机制之一。当一个线程进入被synchronized修饰的方法或代码块时,它会自动获取一个对象的锁。只有当所有线程都退出这个方法或代码块时,才会释放锁。

使用场景

synchronized关键字适用于单机应用中的线程同步,但在分布式系统中,由于存在多个独立的节点,我们需要一种机制来确保这些节点之间的一致性。在这种情况下,synchronized关键字就不再适用,因为它只能同步单个JVM中的线程。

注意事项

  • 死锁:当两个或更多线程互相等待对方释放锁时,就会发生死锁。为了避免这种情况,我们应该尽量减少锁的数量,并确保锁的获取顺序一致。
  • 性能影响:由于synchronized关键字涉及到获取和释放锁的操作,因此它可能会带来一定的性能开销。特别是在多线程竞争激烈的情况下,这种开销会更加明显。
  • 可读性:过多的synchronized关键字可能导致代码难以理解和维护。因此,我们应该尽可能地避免过度使用synchronized,而是寻找更合适的同步机制。

在分布式系统中使用synchronized关键字

虽然synchronized关键字不能直接用于分布式系统中的线程同步,但我们可以利用它来帮助理解分布式锁的工作原理。例如,我们可以将每个节点视为一个JVM,而分布式锁则相当于跨越多个JVM的synchronized关键字。

4、总结

在分布式系统中,我们需要使用分布式锁来实现跨多个节点的线程同步和协调。虽然synchronized关键字本身并不适用于分布式环境,但它可以帮助我们理解分布式锁的工作原理,并且在设计分布式系统时,我们可以借鉴synchronized关键字的一些最佳实践原则。一定要记住,synchronized在分布式系统中是没有作用的,使用synchronized时一定要谨慎,synchronized在单一模块下可用,而涉及远程调用的时候是不可用。

标签:Synchronized,synchronized,ZooKeeper,Redis,关键字,详解,分布式系统,分布式
From: https://blog.csdn.net/weixin_55745942/article/details/139919297

相关文章

  • Redis常见的16个使用场景
    1、缓存String类型例如:热点数据缓存(例如报表、明星出轨),对象缓存、全页缓存、可以提升热点数据的访问数据。2、数据共享分布式String类型,因为Redis是分布式的独立服务,可以在多个应用之间共享例如:分布式Session<dependency><groupId>org.springframework.session</gr......
  • 线程进程以及多线程多进程(超详解)
    目录前言一、什么是进程和线程进程(Process)线程(Thread)多线程(Multithreading)多进程(Multiprocessing)相互组合关系二、资源分配进程私有资源共享资源线程私有资源共享资源多进程私有资源共享资源多线程私有资源共享资源进程的共享和私有资源线......
  • MVCC详解
    什么是MVCC:MVCC(MultiVersionConcurrencyControl的简称),代表多版本并发控制。与MVCC相对的,是基于锁的并发控制,Lock-BasedConcurrencyControl)。MVCC最大的优势:读不加锁,读写不冲突。在读多写少的OLTP应用中,读写不冲突是非常重要的,极大的增加了系统的并发性能学习MVCC前,我们先......
  • SpringBoot集成redis配置文件不生效踩坑记录
    SpringBoot版本<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.2</version></parent>导入spring-boot-stater-data-redis依赖<depen......
  • C语言编译和链接详解(通俗易懂,深入本质)
    我们平时所说的程序,是指双击后就可以直接运行的程序,这样的程序被称为可执行程序(ExecutableProgram)。在Windows下,可执行程序的后缀有.exe和.com(其中.exe比较常见);在类UNIX系统(Linux、MacOS等)下,可执行程序没有特定的后缀,系统根据文件的头部信息来判断是否是可执行程序。可......
  • Redis 高性能基本操作
    单元素操作是基础单元素操作,是指每一种集合类型对单个数据实现增删改查例如,Hash类型的HGET、HSET和HDEL,Set类型的SADD、SREM、SRANDMEMBER等这些操作的复杂度由集合采用的数据结构决定,例如,HGET、HSET和HDEL是对哈希表做操作,所以它们的复杂度都是O(1)Set类型用......
  • 最全Redis数据库Linux安装
    概念所有的I/O操作全在内存中进行,速度非纯快,性能非常搞。如果断电或停止服务,数据就会消失,而内存型数据库恰好可以弥补类似于MySQL等关系型数据库在硬盘当中进行I/O操作的速度上的局限。redis是key-values键值对的存储格式,非关系型安装过程安装redis数据库之前确保在Linux......
  • synchronized 和 ReentrantLock的区别
    synchronized和ReentrantLock的区别  在讨论synchronized和ReentrantLock的区别前,我们先了解一下什么是公平锁和非公平锁  一、公平锁和非公平锁  从公平的角度来说,Java中的锁总共可分为两类:公平锁和非公平锁。但公平锁和非公平锁有哪些区别?孰优孰劣呢?在Java......
  • k8s手撕架构图+详解
    1.架构图这个架构图展示了一个典型的Kubernetes集群的结构和各个组件的作用。以下是详细解释2.架构图整体介绍 ControllerPlane(控制平面)负责管理和控制整个Kubernetes集群。包含以下组件:etcd:一个分布式键值存储,存储集群的所有数据。Scheduler(调度器):负责将Pod......
  • Kubernetes之Service详解
    本文尝试从Service暴露服务方式、Service控制器实现原理、使用规范等方面对Kubernetes中的Service进行详细介绍。一、Kubernetes中的pod有哪些暴露服务的方式各种Kubernetes中暴露服务的方式都有其独特的优缺点,根据具体的使用场景和需求,选择合适的方式非常重要。下面......