Java与Mysql锁相关知识总结

下面我会对Java与MySQL锁相关知识进行总结,并提供两条示例说明。

Java与MySQL锁相关知识总结

常见的锁类型

1. 行级锁(Record Lock)

行级锁可以在单个数据行上进行加锁和解锁,只锁定某个数据行,可以多个事务在同一时间内操作不同的行数据,避免对其他不相关的事务产生影响。InnoDB存储引擎默认使用行级锁。

2. 表级锁(Table Lock)

表级锁是对整张表加锁,锁定后其他事务不能对该表进行修改的操作。

3. 页级锁(Page Lock)

页级锁是将数据分为若干页,对于某一个页的数据进行加锁,比行级锁粗细度更高,但比表级锁细度更小。

锁的特性

锁具有以下几个特性:

  1. 排它性:同一时间内,只能有一个事务对同一资源进行修改,其他事务必须等待。

  2. 持久性:一旦加锁,即使该事务结束,锁也不会自动释放。

3.死锁:如果多个事务同时占用资源并等待其他资源被释放后再继续执行,就会形成死锁。

Java程序中的锁

Java中的锁实现主要有以下几种:

1. synchronized

synchronized是Java中最基本的一种锁机制。可以作用于代码块、方法和类。

示例代码:

public class Sync {
    private int count = 0;

    public void increment() {
        synchronized (this) {
            count++;
        }
    }

    public int getCount() {
        synchronized (this) {
            return count;
        }
    }
}

2. ReentrantLock

ReentrantLock是Java SE5的新特征,类似synchronized一样能够实现同步效果,但是比synchronized更加灵活,可以通过tryLock()方法尝试锁定,lockInterruptibly()方法和tryLock(long time,TimeUnit unit)方法具有可中断性。

示例代码:

public class LockDemo {
    private int count = 0;
    // 创建ReentrantLock实例
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        lock.lock();
        try {
            return count;
        } finally {
            lock.unlock();
        }
    }
}

MySQL中的锁

MySQL中的锁主要有以下两种类型:

1. 共享锁(S锁)

共享锁是读锁,可以被多个线程同时持有,用于保证数据的并发读取。

SELECT * FROM mytable WHERE id=1 LOCK IN SHARE MODE;

2. 排它锁(X锁)

排它锁是写锁,同一时间只能有一个事务占用,用于保证数据的独占性操作。

UPDATE mytable SET field='value' WHERE id=1 LOCK IN SHARE MODE;

示例说明

示例一:Java程序中使用ReentrantLock实现多线程访问共享资源

我们需要实现一个计数器,使用两个线程同时对计数器进行加一操作。

public class Counter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
            System.out.println("Thread " + Thread.currentThread().getId() + " increment count to " + count);
        } finally {
            lock.unlock();
        }
    }
}

在主函数中,我们启动两个线程对计数器进行累加:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                counter.increment();
            }
        });

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                counter.increment();
            }
        });

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

        t1.join();
        t2.join();
    }
}

运行结果:

Thread 12 increment count to 1
Thread 12 increment count to 2
Thread 12 increment count to 3
Thread 12 increment count to 4
Thread 12 increment count to 5
Thread 11 increment count to 6
Thread 11 increment count to 7
Thread 11 increment count to 8
Thread 11 increment count to 9
Thread 11 increment count to 10

可以看到,通过使用ReentrantLock,两个线程能够同时对计数器进行操作,并且线程安全。

示例二:在MySQL中使用共享锁和排它锁

我们需要实现一个存款和取款的实例,存款和取款都需要对账户进行加锁。

CREATE TABLE account (id INT(10) NOT NULL, money INT(10) NOT NULL DEFAULT '0', PRIMARY KEY (id));
INSERT INTO account(id, money) VALUES(1, 100);

BEGIN;
SELECT * FROM account WHERE id=1 LOCK IN SHARE MODE;
UPDATE account SET money=money+100 WHERE id=1;
COMMIT;

BEGIN;
SELECT * FROM account WHERE id=1 FOR UPDATE;
UPDATE account SET money=money-50 WHERE id=1;
COMMIT;

在事务中,使用SELECT ... LOCK IN SHARE MODE可以对记录加共享锁,使用SELECT ... FOR UPDATE可以对记录加排它锁,保证共享和独占性。

以上就是Java与MySQL锁相关知识的总结及示例说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java与Mysql锁相关知识总结 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 接口签名怎么用Java实现

    接口签名是一种验证接口调用合法性的方式,在API开发中经常被使用。接口签名的实现过程需要借助对参数进行加密的算法,而具体的加密算法需要根据接口签名的实现规则来确定。下面我们就来详细讲解如何用Java实现接口签名的过程。 1. 接口签名实现规则 在使用Java实现接口签名之前,必须要明确如下接口签名实现规则。 1.1 参数加密 接口签名需要对参与签名的参数进行…

    Java 2023年5月26日
    00
  • Springmvc异常处理器及拦截器实现代码

    当我们在使用SpringMVC框架进行开发的时候,我们希望在程序运行中出现异常的时候能够进行处理,这时候就需要用到SpringMVC的异常处理器和拦截器。下面是实现这两个功能的代码: SpringMVC异常处理器的实现 首先在SpringMVC配置文件中配置SimpleMappingExceptionResolver,它可以捕获所有未处理的异常,并将它们映射…

    Java 2023年5月27日
    00
  • springboot2.3之后hibernate-validator依赖缺失【踩坑】

    当使用Spring Boot 2.3及以上版本时,可能会遇到hibernate-validator依赖缺失的问题。这是因为Spring Boot 2.3移除了hibernate-validator依赖,而将其替换为了jakarta.validation依赖。因此,在使用hibernate-validator时,需要手动添加jakarta.validation…

    Java 2023年5月20日
    00
  • Java实现经典游戏飞机大战-I的示例代码

    非常感谢您对“Java实现经典游戏飞机大战-I的示例代码”的关注。 下面,我将为大家详细讲解如何实现这个示例代码,并提供两个示例说明。 1. 初步了解示例代码 首先,您需要了解示例代码的基本结构和所包含的类: Main 类:程序的启动入口,用于初始化并启动游戏。 GameFrame 类:游戏窗口,包含了游戏的整个界面,处理用户的输入和绘制游戏元素。 Game…

    Java 2023年5月23日
    00
  • 基于SpringBoot服务端表单数据校验的实现方式

    下面我将为你详细讲解基于SpringBoot服务端表单数据校验的实现方式的完整攻略。本攻略将包含以下内容: 前置条件 SpringBoot服务端表单校验的概念 SpringBoot服务端表单校验方案的实现 两条示例说明 1. 前置条件 在学习本攻略前,你需要具备以下基础知识: Java编程基础 SpringBoot框架的使用 2. SpringBoot服务端…

    Java 2023年6月1日
    00
  • 使用java web 在jsp文件及Class中连接MySQL和SQLserver 的驱动方法

    连接 MySQL 和 SQL Server 数据库需要使用不同的驱动程序,下面我将详细介绍Java Web在JSP文件及Class中连接MySQL和SQL Server驱动的方法。 连接MySQL数据库驱动程序 步骤一:引入MySQL的JDBC驱动 在Java Web项目中连接MySQL数据库,首先需要引入MySQL JDBC驱动程序。将MySQL驱动程序的…

    Java 2023年5月20日
    00
  • SpringBoot 配置文件中配置的中文,程序读取出来是乱码的解决

    当我们在 SpringBoot 配置文件中配置中文时,有时程序运行后会读取出来乱码的情况。这是因为编码不一致或者文件格式问题导致的。下面给出两种解决方法。 解决方法一:设置文件编码 在配置文件中,可以添加如下配置来设置文件编码: spring: messages: encoding: UTF-8 这样,当程序读取配置文件时,会按照 UTF-8 编码格式进行解…

    Java 2023年5月19日
    00
  • 你可能从未使用过的11+个JavaScript特性(小结)

    下面是详细讲解“你可能从未使用过的11+个JavaScript特性(小结)”的攻略。 介绍 本文将讲解11+个在JavaScript中常被忽略的特性。包括可选链操作符、空合并运算符、BigInt、Promise.allSettled()、Array.flat()、Array.flatMap()、Object.fromEntries()、String.trim…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部