Java如何给一段代码加锁

在并发编程中,当多个线程同时访问共享资源时,可能会引发线程安全问题。为了避免这种问题,我们可以使用锁来对关键代码段进行保护,确保同一时间只有一个线程能访问它。

实际问题

假设我们有一个银行账户类,其中包含存款和取款两个方法,我们需要确保这两个方法的并发执行不会出现问题。我们可以使用Java中的锁机制来解决这个问题。

public class BankAccount {
    private double balance;
    private Lock lock = new ReentrantLock();

    public void deposit(double amount) {
        lock.lock();
        try {
            balance += amount;
        } finally {
            lock.unlock();
        }
    }

    public void withdraw(double amount) {
        lock.lock();
        try {
            balance -= amount;
        } finally {
            lock.unlock();
        }
    }
}

在上面的代码中,我们使用了ReentrantLock来创建一个锁对象lock,在depositwithdraw方法中使用lock对关键代码段进行加锁和解锁操作,确保同一时间只有一个线程能执行其中的代码。

示例

下面是一个简单的示例,模拟两个线程并发操作一个银行账户:

public class Main {
    public static void main(String[] args) {
        BankAccount account = new BankAccount();

        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                account.deposit(10);
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                account.withdraw(5);
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final balance: " + account.getBalance());
    }
}

在上面的示例中,我们创建了一个BankAccount对象,并启动两个线程分别对其进行存款和取款操作,最终输出账户的余额。

旅行图

journey
    title Concurrent Bank Account Operations

    section Deposit
        Deposit -> Withdraw: Thread 1
        Withdraw -> Deposit: Thread 2

甘特图

gantt
    title Bank Account Operations
    dateFormat YYYY-MM-DD
    section deposit
    Deposit        :done, 2022-01-01, 2022-01-05
    section withdraw
    Withdraw        :done, 2022-01-02, 2022-01-06

通过使用锁机制,我们可以确保在并发操作下保证数据的一致性和安全性。在实际开发中,对于涉及到共享资源的代码段,加锁是一种非常有效的手段。希望本文对你有所帮助,谢谢阅读!