java线程 - ReadWriteLock(待续。。。)

package com.test.testThread1;

public interface Lock {

    void lock() throws InterruptedException;

    void unlock();
}

package com.test.testThread1;

public class ReadLock implements Lock {

    private ReadWriteLockImpl readWriteLock;

    public ReadLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        synchronized(readWriteLock.getMUTEX()) {
            while (readWriteLock.getWritingWriters() > 0 || readWriteLock.getWaitingWriters() > 0
                    && readWriteLock.getPreferWriter()) {
                readWriteLock.getMUTEX().wait();
            }
            readWriteLock.increaseReadingReaders();
        }
    }

    @Override
    public void unlock() {
        synchronized(readWriteLock.getMUTEX()) {
            readWriteLock.decreaseReadingReaders();
            readWriteLock.changePreferWriter(true);
            readWriteLock.getMUTEX().notifyAll();
        }
    }
}

package com.test.testThread1;

public class WriteLock implements Lock {

    private ReadWriteLockImpl readWriteLock;

    public WriteLock(ReadWriteLockImpl readWriteLock) {
        this.readWriteLock = readWriteLock;
    }

    @Override
    public void lock() throws InterruptedException {
        synchronized(readWriteLock.getMUTEX()) {
            readWriteLock.increaseWaitingWriters();
            try {
                while (readWriteLock.getWritingWriters() > 0 || readWriteLock.getReadingReaders() > 0) {
                    readWriteLock.getMUTEX().wait();
                }
            } finally {
                readWriteLock.decreaseWaitingWriters();
            }
            readWriteLock.increaseWritingWriters();
        }
    }

    @Override
    public void unlock() {
        synchronized(readWriteLock.getMUTEX()) {
            readWriteLock.decreaseWritingWriters();
            readWriteLock.changePreferWriter(false);
            readWriteLock.getMUTEX().notifyAll();
        }
    }
}

package com.test.testThread1;

public interface ReadWriteLock {

    Lock readLock();
    Lock writeLock();
    int getWritingWriters();
    int getWaitingWriters();
    int getReadingReaders();

    static ReadWriteLock readWriteLock() {
        return new ReadWriteLockImpl();
    }

    static ReadWriteLock readWriteLock(boolean preferWriter) {
        return new ReadWriteLockImpl(preferWriter);
    }
}

package com.test.testThread1;

class ReadWriteLockImpl implements ReadWriteLock {

    private int writingWriters = 0;
    private int waitingWriters = 0;
    private int readingReaders = 0;
    private boolean preferWriter = false;
    private final Object MUTEX = new Object();

    public ReadWriteLockImpl() {
        this(true);
    }

    public ReadWriteLockImpl(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

    @Override
    public Lock readLock() {
        return new ReadLock(this);
    }

    @Override
    public Lock writeLock() {
        return new WriteLock(this);
    }

    @Override
    public int getWritingWriters() {
        return this.writingWriters;
    }

    @Override
    public int getWaitingWriters() {
        return this.waitingWriters;
    }

    @Override
    public int getReadingReaders() {
        return this.readingReaders;
    }

    public void increaseWritingWriters() {
        this.writingWriters++;
    }

    public void increaseWaitingWriters() {
        this.waitingWriters++;
    }

    public void increaseReadingReaders() {
        this.readingReaders++;
    }

    public void decreaseWritingWriters() {
        this.writingWriters--;
    }

    public void decreaseWaitingWriters() {
        this.waitingWriters--;
    }

    public void decreaseReadingReaders() {
        this.readingReaders--;
    }

    public Object getMUTEX() {
        return this.MUTEX;
    }

    public void changePreferWriter(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

    public boolean getPreferWriter() {
        return this.preferWriter;
    }
}

package com.test.testThread1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class SharedData {

    private final List container = new ArrayList<>();
    private final ReadWriteLock readWriteLock = ReadWriteLock.readWriteLock();
    private final Lock readLock = readWriteLock.readLock();
    private final Lock writeLock = readWriteLock.writeLock();
    private final int length;

    public SharedData(int length) {
        this.length = length;
    }

    public void write(char c) throws InterruptedException {
        try {
            writeLock.lock();
            container.add(c);
            slowly();
        } finally {
            writeLock.unlock();
        }
    }

    public char read() throws InterruptedException {
        try {
            readLock.lock();
            char c = container.get(container.size() - 1);
            slowly();
            return c;
        } finally {
            readLock.unlock();
        }
    }

    public List getContainer() {
        return this.container;
    }

    public void slowly() {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    

}

package com.test.testThread1;

public class TestReadWriteLock {

    private final static String text = "abcdefghijklmnopqrstuvwxyz#";

    public static void main(String[] args) {
        SharedData sharedData = new SharedData(text.length());
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                for (int j = 0; j < text.length(); j++) {
                    char c = text.charAt(j);
                    try {
                        sharedData.write(c);
                        System.out.println(Thread.currentThread() + " writes " + c);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                while (true) {
                    try {
                        char c = sharedData.read();
                        System.out.println(Thread.currentThread() + " reads " + c);
                        if (c == '#') {
                            break;
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

 

你可能感兴趣的:(多线程)