📅  最后修改于: 2023-12-03 14:43:00.930000             🧑  作者: Mango
在并发编程中,锁是一种用于管理线程间访问共享资源的机制。当多个线程同时访问同一个共享资源时,就可能会出现线程安全问题,其中最主要的问题就是竞态条件(Race Condition)。而锁就可以协调不同线程之间对同一共享资源的访问,确保它们互不干扰。
Java提供了多种锁接口,比如synchronized
关键字、ReentrantLock
、ReadWriteLock
等。这些锁接口都能够保证在多线程环境下,对共享资源的访问是线程安全的。下面分别介绍这些锁接口。
synchronized
关键字是Java中最基本、最常用的锁。通过synchronized
关键字,可以将代码块或方法锁定,使得同一时间只有一个线程能够访问这段代码。
synchronized
锁的是对象而不是代码,即同一个对象的synchronized
代码块是互斥的,不同对象的synchronized
代码块是并行的。
以下是synchronized
关键字的示例代码:
public class SynchronizedDemo {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
在上述代码中,increment
和getCount
方法都是synchronized
方法,即在进入这两个方法之前,线程必须先获得该对象的锁。这样,同一时间只有一个线程能够对count
进行增加或获取。
ReentrantLock
是Java提供的一种可重入锁,相对于synchronized
来说,它具有更高的灵活性和扩展性。
与synchronized
不同,ReentrantLock
具有可中断性、公平性和多条件变量等特性。
以下是ReentrantLock
的示例代码:
public class ReentrantLockDemo {
private ReentrantLock 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();
}
}
}
在上述代码中,increment
和getCount
方法使用了ReentrantLock
锁进行了同步。其中,lock
方法获取锁,unlock
方法释放锁。
ReadWriteLock
是一种读写锁,与ReentrantLock
不同的是,ReadWriteLock
中允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。
以下是ReadWriteLock
的示例代码:
public class ReadWriteLockDemo {
private ReadWriteLock lock = new ReentrantReadWriteLock();
private int count = 0;
public void increment() {
lock.writeLock().lock();
try {
count++;
} finally {
lock.writeLock().unlock();
}
}
public int getCount() {
lock.readLock().lock();
try {
return count;
} finally {
lock.readLock().unlock();
}
}
}
在上述代码中,increment
方法使用了读写锁的写入锁,getCount
方法使用了读写锁的读取锁。这样,多个线程同时访问getCount
方法时,不会被阻塞,只有在需要对共享资源进行写入时才会对线程进行阻塞。
在Java中,锁接口主要有synchronized
关键字、ReentrantLock
和ReadWriteLock
。通过使用这些锁接口,可以在多线程环境下实现对共享资源的线程安全访问。在使用锁的过程中,需要注意锁的粒度和竞态条件问题,以避免出现死锁等线程安全问题。