并发编程中如何使用Java中的锁?
并发编程中如何使用Java中的锁?
在Java中,锁是一种用来控制多个线程访问共享资源的机制。锁可以保证在同一时刻只有一个线程可以访问共享资源,从而避免多个线程同时修改数据导致的数据不一致问题。Java中的锁可以分为两种类型:内置锁和显式锁。
- 内置锁
Java中的每个对象都有一个内置锁,也称为监视器锁。当线程访问一个对象时,它必须先获得该对象的锁,才能进入同步代码块。例如,下面的代码中,线程必须先获得lock对象的锁,才能执行synchronized代码块中的内容。
public class LockDemo {
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// 同步代码块
}
}
}
使用内置锁的好处是它可以自动释放锁。当线程执行完同步代码块后,内置锁会自动释放,其他线程才能获得锁。但是,内置锁的缺点是它的粒度比较粗。如果一个对象有多个同步代码块,那么只有一个线程能够执行这些代码块,其他线程只能等待。
- 显式锁
Java中的显式锁是通过java.util.concurrent.locks包中的Lock接口实现的。与内置锁不同,显式锁可以控制锁的粒度,从而提高程序的并发性能。例如,下面的代码中,我们使用ReentrantLock来实现一个简单的锁。
public class LockDemo {
private final Lock lock = new ReentrantLock();
public void doSomething() {
lock.lock();
try {
// 同步代码块
} finally {
lock.unlock();
}
}
}
使用显式锁的好处是它可以控制锁的粒度。例如,如果一个对象有多个同步代码块,我们可以使用不同的锁来控制每个代码块,从而提高程序的并发性能。但是,显式锁的缺点是它需要手动释放锁,如果程序出现异常或者其他情况导致锁没有被释放,那么就会出现死锁等问题。
- 演示代码
下面是一个简单的演示代码,展示了如何在Java中使用锁来控制并发访问。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
private final Lock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
final LockDemo demo = new LockDemo();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
demo.increment();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
demo.increment();
}
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Count: " + demo.getCount());
}
}
在上面的代码中,我们使用了ReentrantLock来实现锁,通过lock和unlock方法来控制对共享资源的访问。我们创建了两个线程来同时对count变量进行加一操作,最终输出count的值。由于我们使用了锁来控制并发访问,因此最终输出的count的值一定是200000,不会出现数据不一致的问题。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341