Java 层面的锁
在 Java 的多线程中,我们知道可以使用 synchronized 关键字来实现线程间的同步互斥工作, 其实还有一个更优秀的机制去实现 同步互斥的 工作,那就是 Lock 对象。
重入锁 (ReentrantLock)
基本使用:
Lock lock = new ReentrantLock();
// 加锁
lock.lock();
// 解锁
lock.unlock();
更多:公平锁和非公平锁
Lock lock = new ReentrantLock(boolean isFair);
可以传入是否公平的参数,默认是非公平锁,
非公平锁是无序的效率高,
公平锁是有序的,先请求,先获取锁。但效率相对较低
读写锁 (ReentrantReadWriteLock)
ReentrantReadWriteLock, 其核心就是实现读写分离的锁,在高并发下, 尤其是读多写少下,性能高于重入锁。
口诀:读读共享,写写互斥,读写互斥。
package org.mulity.demo;
import java.util.concurrent.locks.*;
/**
* ReentrantReadWriteLock 使用示例
*
* Created by jun on 2017/10/15.
*/
public class UseReentrantReadWriteLock {
private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
private ReentrantReadWriteLock.ReadLock readLock = rwlock.readLock();
private ReentrantReadWriteLock.WriteLock writeLock = rwlock.writeLock();
public void read() {
try {
readLock.lock();
System.out.println("当前线程:" + Thread.currentThread().getName() + "进入");
Thread.sleep(3000);
System.out.println("当前线程:" + Thread.currentThread().getName() + "退出");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock();
}
}
public void write() {
try {
writeLock.lock();
System.out.println("当前线程:" + Thread.currentThread().getName() + "进入");
Thread.sleep(3000);
System.out.println("当前线程:" + Thread.currentThread().getName() + "退出");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock();
}
}
public static void main(String[] args) throws Exception {
final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
urrw.read();
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
urrw.read();
}
}, "t2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
urrw.write();
}
}, "t3");
t1.start();
t2.start();
// t1.start();
// t3.start();
}
}
锁的等待和通知
我们在使用 synchronized的时候,如果需要多线程间进行协作,则需要 Object 的 wait 和 notify, notifyAll 方法进行配合工作,那么同样, 我们在使用 Lock的时候,可以使用一个新的的 等待/通知 的类, 他就是Condition, 这个 Condition 是针对一把锁的,也就是说,只有在锁的基础上才会有Condition
基本使用:
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// 相当于 Object 的 wait();
condition.await();
// 相当于 Object 的 notify();
condition.signal();
// 一个 lock 可以创建多个 Condition