二.多线程设计模式篇-2.3 读写锁分离设计模式

小灰灰 2022-12-10 15:59 193阅读 0赞

多个线程同时读一个资源类是没有任何问题的,所以为了满足在并发的情况下,读取共享资源应该是可以同时进行的;但是,如果一个线程想要去写共享资源,就不应该再有其他线程可以对该共享资源进行读或者是写操作了。

1.读写锁

  1. public class ReadWriteLock {
  2. private int readingReaders = 0;
  3. private int waitingReaders = 0;
  4. private int writingWriters = 0;
  5. private int waitingWriters = 0;
  6. private boolean preferWriter = true;
  7. public ReadWriteLock() {
  8. this(true);
  9. }
  10. public ReadWriteLock(boolean preferWriter) {
  11. this.preferWriter = preferWriter;
  12. }
  13. public synchronized void readLock() throws InterruptedException {
  14. this.waitingReaders++;
  15. try {
  16. while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
  17. this.wait();
  18. }
  19. this.readingReaders++;
  20. } finally {
  21. this.waitingReaders--;
  22. }
  23. }
  24. public synchronized void readUnlock() {
  25. this.readingReaders--;
  26. this.notifyAll();
  27. }
  28. public synchronized void writeLock() throws InterruptedException {
  29. this.waitingWriters++;
  30. try {
  31. while (readingReaders > 0 || writingWriters > 0) {
  32. this.wait();
  33. }
  34. this.writingWriters++;
  35. } finally {
  36. this.waitingWriters--;
  37. }
  38. }
  39. public synchronized void writeUnlock() {
  40. this.writingWriters--;
  41. this.notifyAll();
  42. }
  43. }

2.共享数据

  1. public class SharedData {
  2. private final char[] buffer;
  3. private final ReadWriteLock lock = new ReadWriteLock();
  4. public SharedData(int size) {
  5. this.buffer = new char[size];
  6. for (int i = 0; i < size; i++){
  7. this.buffer[i] = '*';
  8. }
  9. }
  10. public char[] read() throws InterruptedException {
  11. try {
  12. lock.readLock();
  13. return doRead();
  14. } finally {
  15. lock.readUnlock();
  16. }
  17. }
  18. public void write(char c) throws InterruptedException {
  19. try{
  20. lock.writeLock();
  21. doWrite(c);
  22. }finally {
  23. lock.writeUnlock();
  24. }
  25. }
  26. private void doWrite(char c) {
  27. for (int i = 0; i < buffer.length; i++) {
  28. buffer[i] = c;
  29. slowly(10);
  30. }
  31. }
  32. private char[] doRead() {
  33. char[] newBuffer = new char[this.buffer.length];
  34. for (int i = 0; i < newBuffer.length; i++){
  35. newBuffer[i] = this.buffer[i];
  36. }
  37. slowly(50);
  38. return newBuffer;
  39. }
  40. private void slowly(int ms) {
  41. try {
  42. Thread.sleep(ms);
  43. } catch (InterruptedException e) {
  44. }
  45. }
  46. }

3.读工作线程

  1. public class ReadWorker extends Thread {
  2. private final SharedData sharedData;
  3. public ReadWorker(SharedData sharedData) {
  4. this.sharedData = sharedData;
  5. }
  6. @Override
  7. public void run() {
  8. try {
  9. while (true){
  10. char[] buffer = this.sharedData.read();
  11. System.out.println(Thread.currentThread().getName() + " reader: " + String.valueOf(buffer));
  12. }
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }

4.写工作线程

  1. public class WriterWorker extends Thread {
  2. private final String filler;
  3. private final SharedData sharedData;
  4. private int index = 0;
  5. private static final Random random = new Random(System.currentTimeMillis());
  6. public WriterWorker(String filler, SharedData sharedData) {
  7. this.filler = filler;
  8. this.sharedData = sharedData;
  9. }
  10. @Override
  11. public void run() {
  12. while(true){
  13. char c = nextChar();
  14. try {
  15. sharedData.write(c);
  16. Thread.sleep(random.nextInt());
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. private char nextChar() {
  23. char c = filler.charAt(index);
  24. index++;
  25. if (index >= filler.length()){
  26. index = 0;
  27. }
  28. return c;
  29. }
  30. }

5.客户端

  1. public class ReadWriteLockClient {
  2. public static void main(String[] args) {
  3. SharedData sharedData = new SharedData(10);
  4. new ReadWorker(sharedData).start();
  5. new ReadWorker(sharedData).start();
  6. new ReadWorker(sharedData).start();
  7. new ReadWorker(sharedData).start();
  8. new ReadWorker(sharedData).start();
  9. new WriterWorker("qweasdzxc", sharedData).start();
  10. new WriterWorker("QWEASDZXC", sharedData).start();
  11. }
  12. }

发表评论

表情:
评论列表 (有 0 条评论,193人围观)

还没有评论,来说两句吧...

相关阅读