显示锁和内置锁
内置锁(Synchronized)优势
- 代码简洁
- 不会因为没释放锁,导致锁泄露。
显示锁(Lock)优势
- 灵活性强,锁的获取可以被中断,可以尝试获取锁。
- 读多写少等场景。
用法
能用内置锁就用内置锁,不能用内置锁,才考虑用显示锁。
Lock接口
接口主要方法如下:
- lock():获取锁
- tryLock():尝试获取锁,true表示未加锁的情况。
- unlock():释放锁
- newCondition():创建一个Condition
Condition接口
接口主要方法如下:
- await():等待,类似wait方法
- signal():唤醒,类似notify方法
- signalAll():唤醒全部,类似notifAll方法
使用形式
Lock lock = new ReentrantLock();
....
lock.lock();//获取锁
try{
//业务逻辑
}finally{
lock.unlock();//这边要注意释放,不然会导致锁泄露
}
示例
public class LockDemo {
Lock lock = new ReentrantLock();
static int num = 0;
public void addNum(int value) {
lock.lock();
try {
int temp = num;
num = num + value;
Thread.sleep(100);
System.out.println(value + "+" + temp + "=" + num);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
static class AddThread1 extends Thread {
LockDemo lockDemo;
public AddThread1(LockDemo lockDemo) {
this.lockDemo = lockDemo;
}
@Override
public void run() {
lockDemo.addNum(1);
}
}
static class AddThread2 extends Thread {
LockDemo lockDemo;
public AddThread2(LockDemo lockDemo) {
this.lockDemo = lockDemo;
}
@Override
public void run() {
lockDemo.addNum(2);
}
}
public static void main(String[] args) {
LockDemo lockDemo = new LockDemo();
AddThread1 addThread1 = new AddThread1(lockDemo);
AddThread2 addThread2 = new AddThread2(lockDemo);
addThread1.start();
addThread2.start();
}
}
运行结果如下:
结果显示,跟之前synchronized结果是一样的,加锁解锁成功
公平锁和非公平锁
- 公平锁:先进来的线程先执行
- 非公平锁:后进来的线程可能先执行,效率较高。会进行抢锁操作,如果cas获取不到锁,也会进入阻塞队列等到唤醒。
ReentrantLock
构造参数有两个,默认是非公平锁,如果传参是true,则是公平锁。
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。