目录
ReenTrantLock和synchronized有什么区别
AQS是什么?有什么用
特点:
锁和释放锁
和synchronized有什么不同?
首先你可以根据 aqs去设计自己的锁,设计出的锁可以是公平锁,而synchronized只能是非公平锁。而且当线程抢不到锁阻塞等待时可以被打断。
ReenTrantLock和synchronized有什么区别
1.使用区别
Lock是一个接口,而synchronized是关键字,是内置的语言实现。
2.功能区别
(1)可中断锁:体现在lockInterruptibly()方法。如果线程A正在执行锁中代码,线程B正在等待获取该锁,时间太长了,B收到通知不用等了,它就可以中断自己,停止工作了。
(2)锁申请等待限时:体现在tryLock()方法上。
(3)公平锁:ReentrantLock可以实现公平锁,构造函数有一 public ReentrantLock(boolean fair),为true时使用公平锁。
(4)读写锁:读写锁将对一个资源的访问分为两个锁,一个读锁,一个写锁,从而使得读读不互斥,读写互斥以及写写互斥,提高性能。ReadWriteLock就是读写锁,是一个接口,ReentrantReadWriteLock实现了这个接口。可以通过readLock()获取读锁,writeLock()获取写锁。
(5)绑定多个条件:一个ReentrantLock可以绑定多个Condition对象,仅需多次调用new Condition()即可。而在synchronized中锁对象的wait()、notify()/notifyAll()可以实现一个隐含的条件,如果要和多余的条件关联,就不得不使用多个锁。
————————————————
版权声明:本文为CSDN博主「loser与你」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43559950/article/details/120075838
怎么利用AQS设计自己的锁?
设计一个不可重入的独占锁:
package TestAQSDemo;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import static ZBasic.Utils.Sleeper.sleep;
@Slf4j(topic = "c.TestAqs")
public class TestAqs {
public static void main(String[] args) {
MyLock lock = new MyLock();
new Thread(() -> {
lock.lock();
try {
log.debug("locking...");
sleep(1);
} finally {
log.debug("unlocking...");
lock.unlock();
}
},"t1").start();
new Thread(() -> {
lock.lock();
try {
log.debug("locking...");
} finally {
log.debug("unlocking...");
lock.unlock();
}
},"t2").start();
}
}
// 自定义锁(不可重入锁)
class MyLock implements Lock {
// 独占锁 同步器类
class MySync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
if(compareAndSetState(0, 1)) {
// 加上了锁,并设置 owner 为当前线程
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
@Override // 是否持有独占锁
protected boolean isHeldExclusively() {
return getState() == 1;
}
public Condition newCondition() {
return new ConditionObject();
}
}
private MySync sync = new MySync();
@Override // 加锁(不成功会进入等待队列) acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
public void lock() {
sync.acquire(1);
}
@Override // 加锁,可打断
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
@Override // 尝试加锁(一次)
public boolean tryLock() {
return sync.tryAcquire(1);
}
@Override // 尝试加锁,带超时
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
@Override // 解锁
public void unlock() {
sync.release(1);
}
@Override // 创建条件变量
public Condition newCondition() {
return sync.newCondition();
}
}
参考:
黑马JUC
关于Java并发编程 ,可参见gitee项目:
https://gitee.com/trigger333/art-concurrent-book-plus
里面代码主要来自黑马JUC 和 《并发编程的艺术》,我也补充了一些代码,帮助初学者更好的理解和掌握Java JUC.