JavaSE---多线程---锁---Lock
1、ReentrantLock
1.1、可重入锁: 当 某个线程获得到某个锁,可以重复获取相同的锁 而不会 出现死锁;
1.2、可重入锁: synchronized、ReentrantLock
package com.an.lock.reentrantlocks;
/**
* @description:
* @author: anpeiyong
* @date: Created in 2020/6/10 13:51
* @since:
*/
public class SynchronizedTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized (this) {
System.out.println("第1次获取锁,这个锁是:" + this);
int index = 1;
while (true) {
synchronized (this) {
System.out.println("第" + (++index) + "次获取锁,这个锁是:" + this);
}
if (index == 10) {
break;
}
}
}
}
}).start();
}
}
结果:
第1次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第2次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第3次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第4次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第5次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第6次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第7次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第8次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第9次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
第10次获取锁,这个锁是:com.an.lock.reentrantlocks.SynchronizedTest$1@d7f994d
package com.an.lock.reentrantlocks;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @description: 获取锁、释放锁 需要匹配
* @author: anpeiyong
* @date: Created in 2020/6/10 13:53
* @since:
*/
public class LockTest {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock.lock();
System.out.println("第1次获取锁,这个锁是:" + lock);
int index = 1;
while (true) {
try {
lock.lock();
System.out.println("第" + (++index) + "次获取锁,这个锁是:" + lock);
try {
Thread.sleep(new Random().nextInt(200));
} catch (InterruptedException e) {
e.printStackTrace();
}
if (index == 10) {
break;
}
} finally {
lock.unlock();
}
}
} finally {
lock.unlock();
}
}
}).start();
}
}
结果:
第1次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第2次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第3次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第4次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第5次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第6次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第7次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第8次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第9次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
第10次获取锁,这个锁是:java.util.concurrent.locks.ReentrantLock@570ead58[Locked by thread Thread-0]
1.3、ReentrantLock


1.4、ReentrantLock内部类Sync



1.5、AbstractQueuedSynchronizer
组成:volatile修饰的state + 双向链表
实现:
自旋 、CAS 、LockSupport.park()|unpark()
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long stateOffset;
private static final long headOffset;
private static final long tailOffset;
private static final long waitStatusOffset;
private static final long nextOffset;
static {
try {
stateOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("state"));
headOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("head"));
tailOffset = unsafe.objectFieldOffset
(AbstractQueuedSynchronizer.class.getDeclaredField("tail"));
waitStatusOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("waitStatus"));
nextOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("next"));
} catch (Exception ex) { throw new Error(ex); }
}
static final class Node {
}
private transient volatile Node head;
private transient volatile Node tail;
private volatile int state;
//默认非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
}
2、ReentrantReadWriteLock



3、ReentrantLock的锁获取方式
public class ReentrantLock implements Lock, java.io.Serializable {
private final Sync sync;
public void lock() {
sync.lock();
}
abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
}
static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
}
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
public final void acquire(int arg) {
//tryAcquire() acquireQueued() 轮询获取资源
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
//获取失败,当前线程中断
selfInterrupt();
}
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// 快速插入
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//常规插入
enq(node);
return node;
}
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
}
3.2、可轮询
4、公平性
按 线程之间 获取锁的顺序

4.1、公平锁:
线程 顺序请求锁;
4.2、非公平锁:
线程 只有 在锁被占用时等待,允许跳跃获得锁;
5、Lock与synchronized选择
5.1、只有 synchronized 不能满足(比如 可定时锁、公平锁、可中断锁 )使用时,才使用 Lock,否则,推荐synchronized ;
6、ReadWriteLock
6.1、一个资源 同时 被多个线程读取 且 只被一个线程写入;
6.2、读写锁能够提供更好的并发性;
7、ReentrantReadWriteLock
7.1、
public interface ReadWriteLock {
Lock readLock();
Lock writeLock();
}
public class ReentrantReadWriteLock
implements ReadWriteLock, java.io.Serializable {
final Sync sync;
abstract static class Sync extends AbstractQueuedSynchronizer {}
static final class NonfairSync extends Sync {}
static final class FairSync extends Sync {}
public static class ReadLock implements Lock, java.io.Serializable {}
public static class WriteLock implements Lock, java.io.Serializable {}
}

浙公网安备 33010602011771号