Java多线程之读写锁分离设计模式

主要完成任务:

  • 1.read read 并行化
  • 2.read write 不允许
  • 3.write write 不允许
public class ReaderWorker extends Thread {

    private final SharedData data;

    public ReaderWorker(SharedData data) {
        this.data = data;
    }

    @Override
    public void run() {
        while (true) {
            try {
                char[] readBuf = data.read();
                System.out.println(Thread.currentThread().getName() + " reads " + String.valueOf(readBuf));

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
public class ReadWriteLock {

    /**
     * 当前有几个线程 在对它进行读操作
     */
    private int readingReaders = 0;
    /**
     * 当前有几个线程 等待读操作
     */
    private int waitingReaders = 0;

    /**
     * 当前有几个线程 正在写操作
     */
    private int writingWriters = 0;
    /**
     * 当前有几个线程 正在写操作
     */
    private int waitingWriters = 0;

    /**
     * 偏向于写
     */
    private boolean preferWriter = true;

    public ReadWriteLock() {
        this(true);
    }

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

    public synchronized void readLock() throws InterruptedException {
        this.waitingReaders++;
        try {
            /**
             * 让写的线程先运行
             */
            while (writingWriters > 0||(preferWriter&&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();
    }
}

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();
        }
    }

    public void write(char c) throws InterruptedException {
        try {
            lock.writeLock();
            this.doWrite(c);
        } finally {
            lock.writeUnlock();
        }
    }

    private void doWrite(char c) {
        for (int i = 0; i < buffer.length; i++) {
            buffer[i] = c;
            slowly(10);
        }
    }

    private char[] doRead() {
        char[] newBuf = new char[buffer.length];
        for (int i = 0; i < buffer.length; i++) {
            newBuf[i] = buffer[i];
        }
        slowly(50);
        return newBuf;
    }

    private void slowly(int millisecond) {
        try {
            Thread.sleep(millisecond);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class WriterWorker extends Thread {

    private static final Random random = new Random(System.currentTimeMillis());

    private final SharedData data;
    private final String filter;

    private int index = 0;

    public WriterWorker(SharedData data, String filter) {
        this.data = data;
        this.filter = filter;
    }

    @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 = filter.charAt(index);
        index++;
        if (index >= filter.length())
            index = 0;
        return c;
    }
}
/**
 *
 * ReadWriteLock
 */
public class ReadWriteLockClient {
    public static void main(String[] args) {
        final  SharedData sharedData = new SharedData(10);

        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new ReaderWorker(sharedData).start();
        new WriterWorker(sharedData,"123456").start();
        new WriterWorker(sharedData,"abcdef").start();
    }
}

结果:

Thread-0 reads **********
Thread-1 reads **********
Thread-2 reads **********
Thread-3 reads **********
Thread-1 reads aaaaaaaaaa
Thread-3 reads aaaaaaaaaa
Thread-0 reads aaaaaaaaaa
Thread-2 reads aaaaaaaaaa
Thread-1 reads aaaaaaaaaa
Thread-2 reads aaaaaaaaaa
Thread-0 reads aaaaaaaaaa
Thread-3 reads aaaaaaaaaa
Thread-1 reads aaaaaaaaaa
Thread-3 reads aaaaaaaaaa
Thread-0 reads aaaaaaaaaa
Thread-2 reads aaaaaaaaaa
Thread-2 reads aaaaaaaaaa
Thread-0 reads aaaaaaaaaa
Thread-1 reads aaaaaaaaaa
Thread-3 reads aaaaaaaaaa
Thread-2 reads aaaaaaaaaa
Thread-0 reads aaaaaaaaaa
Thread-1 reads aaaaaaaaaa
Thread-3 reads aaaaaaaaaa
Thread-0 reads bbbbbbbbbb
Thread-1 reads bbbbbbbbbb
Thread-2 reads bbbbbbbbbb
Thread-3 reads bbbbbbbbbb
Thread-0 reads bbbbbbbbbb
Thread-1 reads bbbbbbbbbb
Thread-3 reads bbbbbbbbbb
Thread-2 reads bbbbbbbbbb
Thread-0 reads bbbbbbbbbb
Thread-1 reads bbbbbbbbbb
Thread-2 reads bbbbbbbbbb
Thread-3 reads bbbbbbbbbb
Thread-0 reads bbbbbbbbbb
Thread-1 reads bbbbbbbbbb
Thread-3 reads bbbbbbbbbb
Thread-2 reads bbbbbbbbbb
Thread-1 reads 3333333333
Thread-2 reads 3333333333
Thread-3 reads 3333333333
...... 省略

到此这篇关于Java多线程之读写锁分离设计模式的文章就介绍到这了,更多相关Java多线程 读写锁分离内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java多线程编程之读写锁ReadWriteLock用法实例

    读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可.如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁:如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁.总之,读的时候上读锁,写的时候上写锁! 三个线程读数据,三个线程写数据示例: 可以同时读,读的时候不能写,不能同时写,写的时候不能读. 读的时候上读锁,读完解锁:写的时候上写锁,写完解锁. 注意finally解锁. package com.ljq.test.th

  • 举例说明Java多线程编程中读写锁的使用

    以下示例为 java api并发库中 ReentrantReadWriteLock自带的实例,下面进行解读 class CachedData { Object data; volatile boolean cacheValid; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock();//@1 if (!cacheValid) { //

  • Java多线程编程中线程锁与读写锁的使用示例

    线程锁Lock Lock  相当于 当前对象的 Synchronized import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* * Lock lock = new ReentrantLock(); * lock.lock(); lock.unLock(); * 类似于 synchronized,但不能与synchronized 混用 */ public class L

  • java多线程-读写锁原理

    Java5 在 java.util.concurrent 包中已经包含了读写锁.尽管如此,我们还是应该了解其实现背后的原理. 读/写锁的 Java 实现(Read / Write Lock Java Implementation) 读/写锁的重入(Read / Write Lock Reentrance) 读锁重入(Read Reentrance) 写锁重入(Write Reentrance) 读锁升级到写锁(Read to Write Reentrance) 写锁降级到读锁(Write to

  • Java多线程之读写锁分离设计模式

    主要完成任务: 1.read read 并行化 2.read write 不允许 3.write write 不允许 public class ReaderWorker extends Thread { private final SharedData data; public ReaderWorker(SharedData data) { this.data = data; } @Override public void run() { while (true) { try { char[]

  • java并发编程StampedLock高性能读写锁详解

    目录 一.读写锁 二.悲观读锁 三.乐观读 一.读写锁 在我的<java并发编程>上一篇文章中为大家介绍了<ReentrantLock读写锁>,ReentrantReadWriteLock可以保证最多同时有一个线程在写数据,或者可以同时有多个线程读数据,但读写不能同时进行. 比如你正在做的是日志,有一个线程正在做写操作,但是在写日志的时候你可能需要把日志集中转移到集中管理日志服务,但是此时读线程不能读数据(因为无法获取读锁).面对这个需求,ReentrantReadWriteLoc

  • C#使用读写锁三行代码简单解决多线程并发的问题

    在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三方日志插件,也可以选择使用数据库,还可以自己写个简单的方法把错误信息记录到日志文件. 选择最后一种方法实现的时候,若对文件操作与线程同步不熟悉,问题就有可能出现了,因为同一个文件并不允许多个线程同时写入,否则会提示"文件正在由另一进程使用,因此该进程无法访问此文件". 这是文件的并发写入问题,就需要用到线程同步.而微软也给线程同步提供了一些相关的类可以达到这样的目的,本文使用到的 System.Thr

  • Java中读写锁ReadWriteLock的原理与应用详解

    目录 什么是读写锁? 为什么需要读写锁? 读写锁的特点 读写锁的使用场景 读写锁的主要成员和结构图 读写锁的实现原理 读写锁总结 Java并发编程提供了读写锁,主要用于读多写少的场景,今天我就重点来讲解读写锁的底层实现原理 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的. 所谓的读

  • Java读写锁ReadWriteLock原理与应用场景详解

    Java并发编程提供了读写锁,主要用于读多写少的场景 什么是读写锁? 读写锁并不是JAVA所特有的读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的. 所谓的读写锁(Readers-Writer Lock),顾名思义就是将一个锁拆分为读锁和写锁两个锁. 其中读锁允许多个线程同时获得,而写锁则是互斥锁,不允许多个线程同时获得写锁,

  • Java多线程之锁学习(增强版)

    目录 阻塞锁 非阻塞锁 锁的四种状态 无锁状态 偏向锁 轻量级锁 重量级锁 可重入锁 自旋锁 读写锁 互斥锁 悲观锁 乐观锁 公平锁 非公平锁 显示锁和内置锁 轮询锁和定时锁 对象锁和类锁 锁粗化 锁消除 信号量 独享锁 共享锁 分段锁 死锁案例和排查 阻塞锁 含义:多个线程同时调用一个方法的时候,所有的线程都被排队处理了,让线程进入阻塞状态进行等待,当获得相应的信号(唤醒.时间)时,才能进入线程的准备就绪的状态.通过竞争.进入运行状态. Java中,能够进入\退出.阻塞状态或包含阻塞锁的方法有

  • Java多线程读写锁ReentrantReadWriteLock类详解

    目录 ReentrantReadWriteLock 读读共享 写写互斥 读写互斥 源码分析 写锁的获取与释放 读锁的获取与释放 参考文献 真实的多线程业务开发中,最常用到的逻辑就是数据的读写,ReentrantLock虽然具有完全互斥排他的效果(即同一时间只有一个线程正在执行lock后面的任务),这样做虽然保证了实例变量的线程安全性,但效率却是非常低下的.所以在JDK中提供了一种读写锁ReentrantReadWriteLock类,使用它可以加快运行效率. 读写锁表示两个锁,一个是读操作相关的锁

随机推荐