Lock
tryLock() 代码示例
- 看下注释
ReentrantLock lock = new ReentrantLock();
Runnable runnable = () -> {
// 1. 获取锁的时候可能会被中断,中断就不需要拿锁了
try {
if (lock.tryLock(1, TimeUnit.SECONDS)) {
// 2. 要确保拿到锁之后进行解锁
try {
System.out.println(Thread.currentThread().getName() + "拿到锁了");
TimeUnit.MILLISECONDS.sleep(800);
} finally {
lock.unlock();
}
} else {
System.out.println(Thread.currentThread().getName() + "没有到锁了");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
lockInterruptibly
ReentrantLock lock = new ReentrantLock();
Runnable runnable = () -> {
try {
lock.lockInterruptibly();
try{
System.out.println("拿到锁了");
TimeUnit.MILLISECONDS.sleep(800);
} catch (InterruptedException e) {
System.out.println("获得锁后被中断");
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
System.out.println("获得锁期间被中断");
}
};
Thread a = new Thread(runnable);
a.start();
// 1. 要求获得锁之后中断
// TimeUnit.MILLISECONDS.sleep(200);
// a.interrupt();
// 获得锁期间被中断
// 2. a.interrupt();
锁的分类
乐观锁悲观锁
可重入/递归锁
公平/非公平
![锁 - 图5](/uploads/projects/scp166@java/ed6aa52703aab5ef9904c32beb3d37fa.svg)
共享锁/排他锁
![锁 - 图6](/uploads/projects/scp166@java/ad1193fa06eec1d793409f43437a8020.svg)
读写锁使用代码
public class TryLockTest {
// 创建读写锁
private static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 拿到读写锁实例的读锁
private static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 拿到读写锁实例的写锁
private static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 读操作
public static void read() {
readLock.lock();
try {
System.out.println(Thread.currentThread().getName() + "获得了读锁");
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "准备解除读锁");
readLock.unlock();
}
}
// 写操作
public static void write() {
writeLock.lock();
try {
System.out.println(Thread.currentThread().getName() + "获得了写锁");
TimeUnit.MILLISECONDS.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + "准备解除写锁");
writeLock.unlock();
}
}
public static void testReentrantReadWriteLock() throws InterruptedException {
int size = 10;
Runnable read = ()-> {
read();
};
Runnable write = ()-> {
write();
};
// 一半进行共享读
Thread[] threads = new Thread[size];
for (int i=0; i<size / 2; i++) {
threads[i] = new Thread(read);
}
// 一半进行排他写
for (int i=size/2; i<size; i++) {
threads[i] = new Thread(write);
}
for (int i=0; i<size; i++) {
threads[i].start();
}
for (int i=0; i<size; i++) {
threads[i].join();
}
}
}
自选锁
可中断
锁的优化
![锁 - 图9](/uploads/projects/scp166@java/7462f0c5f8bf0751a33065114e4dc6cc.svg)