锁
一、作用
二、代码
package com.intellif.mozping.lockp.rwl;
import com.intellif.mozping.tools.SleepTools;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author by mozping
* @Classname ReadWriteLockTest
* @Description TODO
* @Date 2019/1/2 20:07
*/
public class ReadWriteLockTest {
private static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static Lock writeLock = readWriteLock.writeLock();
private static Lock readLock = readWriteLock.readLock();
public static void main(String[] args) {
System.out.println("测试写锁---------------------------------");
for (int i = 1; i <= 3; i++) {
new MyWriteThread().start();
}
SleepTools.second(10);
System.out.println("测试读锁---------------------------------");
for (int i = 1; i <= 3; i++) {
new MyReadThread().start();
}
}
private static class MyWriteThread extends Thread {
@Override
public void run() {
writeLock.lock();
System.out.println("[" + Thread.currentThread().getName() + "] 拿到锁了,做点事情....");
SleepTools.randomMs(3000);
System.out.println("[" + Thread.currentThread().getName() + "] 做完了....");
writeLock.unlock();
}
}
private static class MyReadThread extends Thread {
@Override
public void run() {
readLock.lock();
System.out.println("[" + Thread.currentThread().getName() + "] 拿到锁了,做点事情....");
SleepTools.randomMs(3000);
System.out.println("[" + Thread.currentThread().getName() + "] 做完了....");
readLock.unlock();
}
}
}
输出:
测试写锁---------------------------------
[Thread-0] 拿到锁了,做点事情....
[Thread-0] 做完了....
[Thread-1] 拿到锁了,做点事情....
[Thread-1] 做完了....
[Thread-2] 拿到锁了,做点事情....
[Thread-2] 做完了....
测试读锁---------------------------------
[Thread-3] 拿到锁了,做点事情....
[Thread-4] 拿到锁了,做点事情....
[Thread-5] 拿到锁了,做点事情....
[Thread-5] 做完了....
[Thread-4] 做完了....
[Thread-3] 做完了....
结论:
写锁只能被一个线程拿到,读锁可以被多个线程拿到;
三、Demo
package com.intellif.mozping.lockp.rwl;
import com.intellif.mozping.tools.SleepTools;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author by mozping
* @Classname SimulateDbAccess
* @Description 模拟数据库的访问,有2个写入的线程和10个读取的线程
* @Date 2019/1/2 20:20
*/
public class SimulateDbAccess {
private static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private static Lock readLock = readWriteLock.readLock();
private static Lock writeLock = readWriteLock.writeLock();
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
new MyReadDbThread().start();
}
for (int i = 0; i < 1; i++) {
new MyWriteDbThread().start();
}
}
private static class MyReadDbThread extends Thread {
@Override
public void run() {
for (; ; ) {
try {
readLock.lock();
System.out.println("[" + Thread.currentThread().getName() + "]读取线程读取数据库开始...");
SleepTools.ms(3000);
System.out.println("[" + Thread.currentThread().getName() + "]读取线程读取数据库结束...");
} catch (Exception e) {
} finally {
readLock.unlock();
}
//休眠片刻
SleepTools.ms(2000);
}
}
}
private static class MyWriteDbThread extends Thread {
@Override
public void run() {
for (; ; ) {
try {
writeLock.lock();
System.out.println("[" + Thread.currentThread().getName() + "]写入线程写入数据库开始...");
SleepTools.ms(5000);
System.out.println("[" + Thread.currentThread().getName() + "]写入线程写入数据库结束...");
} catch (Exception e) {
} finally {
writeLock.unlock();
}
//休眠片刻
SleepTools.ms(3000);
}
}
}
}
结论:
写锁可以阻塞读锁,写入线程获取到写锁写入的期间,读线程是获取不到锁,无法读取的,。