一.ReentrantLock(可重入锁)
即可重入锁。
具体可看:https://mp.csdn.net/mdeditor/100807462#
例:
class Clerk {
private int product = 0;//共享数据
private Lock lock = new ReentrantLock();//创建锁对象
private Condition condition = lock.newCondition();//获取condition实例
public void get() { //进货
lock.lock();//上锁
try {
while (product >= 1) {
System.out.println("产品已满");
try {
condition.await();//满了就等待
} catch (InterruptedException e) {
}
}
System.out.println(Thread.currentThread().getName() + ":" + (++product));
condition.signalAll();//没满就可以进货
}finally {
lock.unlock();//释放锁
}
}
public void sell() {//卖货
lock.lock();//上锁
try {
while (product <= 0) {
System.out.println("缺货");
try {
condition.await();//缺货就等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + ":" + (--product));
condition.signalAll();//不缺货就可以卖
}finally {
lock.unlock();//释放锁
}
}
}
二.ReentrantReadWriteLock类中的静态内部类ReadLock(读-写锁)
与互斥锁定相比,读-写锁定允许对共享数据进行更高级别的并发访问。虽然一次只有一个线(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(reader 线程)。从理论上讲,与互斥锁定相比,使用读-写锁定所允许的并发性增强将带来更大的性能提高。
写写/读写需要互斥,读读不需要互斥。
三.ReentrantReadWriteLock类中的静态内部类WriteLock(读-写锁)
与互斥锁定相比,读-写锁定允许对共享数据进行更高级别的并发访问。虽然一次只有一个线(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程可以同时读取共享数据(reader 线程)。从理论上讲,与互斥锁定相比,使用读-写锁定所允许的并发性增强将带来更大的性能提高。
写写/读写需要互斥,读读不需要互斥。
例:
public class TestReadWriterLock {
public static void main(String[] args){
ReadWriterLockDemo rw = new ReadWriterLockDemo();
new Thread(new Runnable() {//一个线程写
@Override
public void run() {
rw.set((int)Math.random()*101);
}
},"write:").start();
for (int i = 0;i<100;i++){//100个线程读
Runnable runnable = () -> rw.get();
Thread thread = new Thread(runnable);
thread.start();
}
}
}
class ReadWriterLockDemo{
private int number = 0;
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//读(可以多个线程同时操作)
public void get(){
readWriteLock.readLock().lock();//上锁
try {
System.out.println(Thread.currentThread().getName()+":"+number);
}finally {
readWriteLock.readLock().unlock();//释放锁
}
}
//写(一次只能有一个线程操作)
public void set(int number){
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName());
this.number = number;
}finally {
readWriteLock.writeLock().unlock();
}
}
}
参考:https://blog.csdn.net/m0_38110132/article/details/74571805
https://www.jianshu.com/p/1f19835e05c0