读写锁分离设计
2019-01-02 本文已影响0人
程序设计法师
public interface Lock {
//获取显示锁,没有获得锁的线程将被阻塞
void lock() throws InterruptedException;
//释放获取的锁
void unlock();
}
public interface ReadWriteLock {
//创建reader锁
Lock readLock();
//创建write锁
Lock writeLock();
//获取当前有多少线程正在执行写操作
int getWritingWriters();
//获取当前有多少个线程正在等待获取写入锁
int getWaitingWriters();
//获取当前有多少个线程正在等待获取reader锁
int getReadingReaders();
//工厂方法,创建ReaderWriteLock
static ReadWriteLock readWriteLock(){
return new ReadWriteLockImpl();
}
//工厂方法,创建ReadWriteLock,并且传入preferWriter
static ReadWriteLock readWriteLock(boolean preferWriter)
{
return new ReadWriteLockImpl(preferWriter);
}
}
public class ReadWriteLockImpl implements ReadWriteLock {
//定义对象锁
private final Object MUTEX=new Object();
//当前有多少个线程正在写入
private int writingWriters=0;
//当前有多少个线程正在等待写入
private int waitingWriters=0;
//当前有多少个线程正在read
private int readingReaders=0;
//read和write的偏好设置
private boolean preferWriter;
//默认情况下perferWriter为true
public ReadWriteLockImpl() {
this(true);
}
public ReadWriteLockImpl(boolean preferWriter) {
this.preferWriter = preferWriter;
}
//创建read lock
@Override
public Lock readLock() {
return new ReadLock(this);
}
@Override
public Lock writeLock() {
return new WriteLock(this);
}
//使写线程的数量增加
public void incrementWritingWriters(){
this.writingWriters++;
}
//使写线程的数量减少
public void decrementWritingWriters(){
this.writingWriters--;
}
//获取当前有多少个线程正在进行写操作
@Override
public int getWritingWriters() {
return writingWriters;
}
//使等待写入的线程的数量增加
public void incrementWaitingWriters(){
this.waitingWriters++;
}
//使等待获取写入锁的数量减少
public void decrementWaitingWriters(){
this.waitingWriters--;
}
//获取当前有多少个线程正在等待获取写入锁
@Override
public int getWaitingWriters() {
return waitingWriters;
}
//使读线程的数量增加
public void incrementReadingReaders(){
this.readingReaders++;
}
//使读取线程的数量减少
public void decrementReadingReaders(){
this.readingReaders--;
}
//获取当前有多少个线程正在进行读操作
@Override
public int getReadingReaders() {
return this.readingReaders;
}
//获取对象锁
Object getMutex(){
return this.MUTEX;
}
//获取当前是否偏向写锁
boolean getPreferWriter(){
return this.preferWriter;
}
//设置写锁偏好
public void changePrefer(boolean preferWriter){
this.preferWriter=preferWriter;
}
}
public class ReadLock implements Lock {
private final ReadWriteLockImpl mReadWriteLock;
public ReadLock(ReadWriteLockImpl readWriteLock) {
mReadWriteLock = readWriteLock;
}
@Override
public void lock() throws InterruptedException {
//使用Mutex作为锁
synchronized (mReadWriteLock.getMutex()){
//若此时有线程在进行写操作,或者有写线程在等待并且偏向写锁的标识为true时,就会无法获取该锁,只能被挂起
while(mReadWriteLock.getWaitingWriters()>0
||(mReadWriteLock.getPreferWriter()&&mReadWriteLock.getWaitingWriters()>0)){
mReadWriteLock.getMutex().wait();
}
//成功获得读锁,并且使readingReaders的数量增加
mReadWriteLock.incrementReadingReaders();
}
}
@Override
public void unlock() {
//使用Mutex作为锁,并且进行同步
synchronized (mReadWriteLock.getMutex()){
//释放锁的过程就是使得当前reading的数量减1
//将perferWriter设置为true,可以使得writer线程获得更多的机会
//通知唤醒与Mutex关联的monitor waitSet中的线程
mReadWriteLock.decrementReadingReaders();
mReadWriteLock.changePrefer(true);
mReadWriteLock.getMutex().notifyAll();
}
}
}
public class WriteLock implements Lock {
private final ReadWriteLockImpl mReadWriteLock;
public WriteLock(ReadWriteLockImpl readWriteLock) {
mReadWriteLock = readWriteLock;
}
@Override
public void lock() throws InterruptedException {
synchronized (mReadWriteLock.getMutex()){
try {
//首先使等待获取写入锁的数字加1
mReadWriteLock.incrementWaitingWriters();
//如果此时有其他线程正在进行读操作,或者写操作,那么当前线程将被挂起
while (mReadWriteLock.getReadingReaders() > 0
|| (mReadWriteLock.getWritingWriters() > 0)) {
mReadWriteLock.getMutex().wait();
}
}finally {
//成功获取到了写入锁,使得等待获取写入锁的计数器减1
this.mReadWriteLock.decrementWaitingWriters();
}
//将正在写入的线程数量加1
mReadWriteLock.incrementWritingWriters();
}
}
@Override
public void unlock() {
synchronized (mReadWriteLock.getMutex()){
//减少正在写入锁的线程计数器
mReadWriteLock.decrementWritingWriters();
//将偏好状态修改为false,可以使得读锁被最快速的获得
mReadWriteLock.changePrefer(false);
//通知唤醒其他在Mutex,monitor waitset中的线程
mReadWriteLock.getMutex().notifyAll();
}
}
}
public class ShareData {
//定义共享数据
private final List<Character> container=new ArrayList<>();
//构造ReadWriteLock
private final ReadWriteLock mReadWriteLock= ReadWriteLock.readWriteLock();
//创建读取锁
private final Lock readLock=mReadWriteLock.readLock();
//创建写入锁
private final Lock writeLock=mReadWriteLock.writeLock();
private final int length;
public ShareData(int length) {
this.length = length;
}
public char[] read(){
try {
readLock.lock();
char[] newBuffer=new char[container.size()];
for (int i = 0; i < container.size(); i++) {
newBuffer[i]=container.get(i);
}
slowly();
return newBuffer;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//当所有的操作都完成之后,对写锁进行释放
writeLock.unlock();
}
return null;
}
public void write(char c){
try {
writeLock.lock();
this.container.add(c);
slowly();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//当所有的操作都完成之后,对写锁进行释放
writeLock.unlock();
}
}
private void slowly(){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ReadWriteLockTest {
private final static String text="This";
public static void main(String [] args){
//定义共享数据
final ShareData shareData=new ShareData(text.length()*9);
//创建两个线程进行数据写操作
for (int i = 0; i < 9; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int j = 0; j < text.length(); j++) {
char c=text.charAt(j);
shareData.write(c);
System.out.println(currentThread()+"write"+c);
}
}
}).start();
}
//创建10个线程进行数据读操作
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println(currentThread() + "read: " + new String(shareData.read()));
}
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
}
}
Thread[Thread-0,5,main]write: T
Thread[Thread-0,5,main]write: h
Thread[Thread-4,5,main]write: T
Thread[Thread-1,5,main]write: T
Thread[Thread-5,5,main]write: T
Thread[Thread-5,5,main]write: h
Thread[Thread-1,5,main]write: h
Thread[Thread-7,5,main]write: T
Thread[Thread-8,5,main]write: T
Thread[Thread-6,5,main]write: T
Thread[Thread-0,5,main]write: i
Thread[Thread-0,5,main]write: s
Thread[Thread-7,5,main]write: h
Thread[Thread-7,5,main]write: i
Thread[Thread-7,5,main]write: s
Thread[Thread-1,5,main]write: i
Thread[Thread-6,5,main]write: h
Thread[Thread-2,5,main]write: T
Thread[Thread-2,5,main]write: h
Thread[Thread-2,5,main]write: i
Thread[Thread-5,5,main]write: i
Thread[Thread-5,5,main]write: s
Thread[Thread-1,5,main]write: s
Thread[Thread-8,5,main]write: h
Thread[Thread-8,5,main]write: i
Thread[Thread-8,5,main]write: s
Thread[Thread-2,5,main]write: s
Thread[Thread-4,5,main]write: h
Thread[Thread-4,5,main]write: i
Thread[Thread-6,5,main]write: i
Thread[Thread-6,5,main]write: s
Thread[Thread-3,5,main]write: T
Thread[Thread-3,5,main]write: h
Thread[Thread-3,5,main]write: i
Thread[Thread-4,5,main]write: s
Thread[Thread-3,5,main]write: s
Thread[Thread-13,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-9,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-16,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-12,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-10,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-17,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-12,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-18,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-16,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-11,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-10,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss
Thread[Thread-9,5,main]read: ThTTThhTTTishisihThiisshisshiisThiss