zoukankan      html  css  js  c++  java
  • 多线程读写锁分离设计模式

    一、concern conflict(同时发生以下两种操作是否会发生数据冲突)

    1.read read false 可以并行化
    2.write read true 需要串行化
    3.read write true 需要串行化
    4.write write true 需要串行化

    二、多线程读写锁分离

    读写锁

    package com.dwz.concurrency2.chapter7;
    
    public class ReadWriteLock {
        private int readingReaders = 0;//正在读(当前有几个线程正在进行读的操作)
        private int waitingReaders = 0;//等待正在读(有几个线程想读,但是读不了)
        private int writingWriters = 0;//正在写(当前有几个线程正在进行写的操作)
        private int waitingWriters = 0;//等待正在写(有几个线程想写,但是锁被占用,写不了)
        private boolean perferWriter = true;//增加写的几率
        
        public ReadWriteLock() {
            this(true);
        }
        
        public ReadWriteLock(boolean perferWriter) {
            this.perferWriter = perferWriter;
        }
        
        public synchronized void readLock() throws InterruptedException {
            this.waitingReaders++;
            try {
                while (writingWriters > 0 || (perferWriter && waitingWriters > 0)) {
                    this.wait();
                } 
                this.readingReaders++;
            } finally {
                this.waitingReaders--;
            }
        }
        
        public synchronized void readUnlock() {
            this.readingReaders--;
            this.notifyAll();
        }
        
        public synchronized void writeLock() throws InterruptedException {
            this.waitingWriters++;
            try {
                while (readingReaders > 0 || writingWriters > 0) {
                    this.wait();
                }
                this.writingWriters++;
            } finally {
                this.waitingWriters--;
            }
        }
        
        public synchronized void writeUnlock() {
            this.writingWriters--;
            this.notifyAll();
        }
    }

    共享数据

    package com.dwz.concurrency2.chapter7;
    
    public class SharedData {
        private final char[] buffer;
        private final ReadWriteLock lock = new ReadWriteLock();
        
        public SharedData(int size) {
            this.buffer = new char[size];
            for(int i = 0; i < size; i++) {
                this.buffer[i] = '*';
            }
        }
        
        public char[] read() throws InterruptedException {
            try {
                lock.readLock();
                return this.doRead();
            } finally {
                lock.readUnlock();
            }
        }
        
        private char[] doRead() throws InterruptedException {
            char[] newBuf = new char[buffer.length];
            for(int i = 0; i < buffer.length; i++) {
                newBuf[i] = buffer[i];
            }
            Thread.sleep(50);
            return newBuf;
        }
        
        public void write(char c) throws InterruptedException {
            try {
                lock.writeLock();
                this.doWrite(c);
            } finally {
                lock.writeUnlock();
            }
        }
    
        private void doWrite(char c) throws InterruptedException {
            for(int i = 0; i < buffer.length; i++) {
                buffer[i] = c;
                Thread.sleep(10);
            }
        }
        
        
    }

    读线程

    package com.dwz.concurrency2.chapter7;
    
    public class ReaderWorker extends Thread {
        private final SharedData data;
    
        public ReaderWorker(SharedData data) {
            this.data = data;
        }
    
        @Override
        public void run() {
            try {
                while (true) {
                    char[] readBuf = data.read();
                    System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    写线程

    package com.dwz.concurrency2.chapter7;
    
    import java.util.Random;
    
    public class WriterWorker extends Thread {
        private static final Random random = new Random(System.currentTimeMillis());
        private final SharedData data;
        private final String filler;
        private int index = 0;
        
        public WriterWorker(SharedData data, String filler) {
            this.data = data;
            this.filler = filler;
        }
        
        @Override
        public void run() {
            try {
                while(true) {
                    char c = nextChar();
                    data.write(c);
                    Thread.sleep(random.nextInt(1000));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        private char nextChar() {
            char c = filler.charAt(index);
            index++;
            if(index > filler.length()) {
                index = 0;
            }
            return c;
        }
    }

    测试

    package com.dwz.concurrency2.chapter7;
    /**
     * ReadWriteLock design pattern
     * Reader-Writer design pattern
     */
    public class ReaderWriterClient {
        public static void main(String[] args) {
            final SharedData data = new SharedData(10);
            new ReaderWorker(data).start();
            new ReaderWorker(data).start();
            new ReaderWorker(data).start();
            new ReaderWorker(data).start();
            new ReaderWorker(data).start();
            new WriterWorker(data, "sdhkfhsdkfshdf").start();
            new WriterWorker(data, "SDHKFHSDKFSHDF").start();
        }
    }
  • 相关阅读:
    错误1053:服务没有及时响应启动或控制请求
    错误号码2003 Can't connect to MySQL server 'localhost' (0)
    分析slow-log 每小时慢sql情况
    用spring annotation声明的bean,当打包在jar中时,无法被扫描到
    mysql 锁查看
    linux 使用expect
    tomcat启动报错:java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener
    Spring LDAP authenticate method with Pooling
    一步步教你使用Proguard混淆Java源代码
    JAVA获取CLASSPATH路径
  • 原文地址:https://www.cnblogs.com/zheaven/p/12120886.html
Copyright © 2011-2022 走看看