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