Java给变量加锁及等待

引言

在并发编程中,多个线程可能会同时访问和修改共享变量,这种情况下就需要使用锁来保证线程安全。Java提供了synchronized关键字和Lock接口来实现对变量的加锁操作。本文将介绍如何在Java中给变量加锁并进行等待操作,以及相关的代码示例。

加锁操作

  1. synchronized关键字 synchronized关键字是Java提供的最基本的加锁操作方式。它可以用来修饰方法或代码块。当一个线程访问被synchronized修饰的方法或代码块时,其他线程将被阻塞,直到当前线程释放锁。

下面是一个使用synchronized关键字对变量加锁的示例代码:

public class Counter {
    private int count;

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

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

在上述代码中,我们通过synchronized关键字修饰了increment()getCount()方法,从而实现对count变量的加锁操作。

  1. Lock接口 除了使用synchronized关键字外,还可以使用Lock接口实现对变量的加锁操作。Lock接口提供了更灵活的锁定方式,可以支持更复杂的同步需求。

下面是一个使用Lock接口对变量加锁的示例代码:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

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

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

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

在上述代码中,我们使用ReentrantLock类实现了Lock接口,并通过lock()unlock()方法对count变量进行加锁和解锁操作。

等待操作

在多线程编程中,有时候需要让一个线程等待另一个线程的某个条件满足后再执行。Java提供了wait()和notify()方法来实现线程之间的等待和通知机制。

下面是一个使用wait()和notify()方法实现线程等待的示例代码:

public class MyWaitNotify {
    private boolean wasSignalled = false;

    public synchronized void doWait() throws InterruptedException {
        while (!wasSignalled) {
            wait();
        }
        // 清除信号
        wasSignalled = false;
    }

    public synchronized void doNotify() {
        wasSignalled = true;
        notify();
    }
}

在上述代码中,我们定义了一个wasSignalled变量来表示是否有信号通知。doWait()方法使用了wait()方法来使线程等待,直到wasSignalled为true。doNotify()方法通过notify()方法发送信号通知。

流程图

下面是一个使用mermaid语法绘制的加锁与等待操作的流程图:

flowchart TD
    start[开始]
    subgraph 加锁操作
        A[获取锁]
        B[执行加锁代码]
        C[释放锁]
    end
    subgraph 等待操作
        D[检查条件]
        E[等待]
        F[唤醒]
    end
    start --> A
    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> D

总结

本文介绍了在Java中给变量加锁及进行等待操作的方法。我们可以使用synchronized关键字或Lock接口来实现加锁操作,使用wait()和notify()方法来实现线程之间的等待和通知。加锁和等待操作可以保证多线程程序的线程安全性和正确性。

通过本文的介绍和示例代码,希望读者能够加深对Java中加锁和等待操作的理解,从而更好地进行并发编程。