ReentrantReadWriteLock锁例子

锁所提供的最重要的改进之一就是ReadWriteLock接口和唯一 一个实现它的ReentrantReadWriteLock类。这个类提供两把锁,一把用于读操作和一把用于写操作。同时可以有多个线程执行读操作,但只有一个线程可以执行写操作。当一个线程正在执行一个写操作,不可能有任何线程执行读操作。

参考http://ifeve.com/basic-thread-synchronization-6/#more-7030 做了优化的例子
创建了5个读线程、一个写线程,分别读10次、写3次

PricesInfo

package threadTest.reentrantReadWriteLockTest;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class PricesInfo {
    private double price1;
    private double price2;

    private ReadWriteLock lock;

    public PricesInfo() {
        this.price1 = 1.0;
        this.price2 = 2.0;
        this.lock = new ReentrantReadWriteLock();
    }

    public double getPrice1() {
        lock.readLock().lock();
        System.out.printf("%s : Price1 开始读了!\n" ,Thread.currentThread().getName());
        double value = price1;
        System.out.printf("%s : Price1 读取完毕 : %f\n"
                ,Thread.currentThread().getName(),value);
        lock.readLock().unlock();
        return value;
    }

    public double getPrice2() {
        lock.readLock().lock();
        System.out.printf("%s : Price2开始读了!\n" ,Thread.currentThread().getName());
        double value = price2;
        System.out.printf("%s : Price2读取完毕 : %f\n"
                ,Thread.currentThread().getName(),value);
        lock.readLock().unlock();
        return value;
    }

    public void setPrices(double price1, double price2) {
        lock.writeLock().lock();
        System.out.printf("Writer:Attempt to modify the price.\n");
        this.price2 = price2;
        this.price1 = price1;

        System.out.printf("Writer:Prices have been modified.\n");
        lock.writeLock().unlock();

    }

}
Reader
package threadTest.reentrantReadWriteLockTest;

public class Reader implements Runnable {
    private PricesInfo priceInfo;

    public Reader(PricesInfo priceInfo) {
        this.priceInfo = priceInfo;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            priceInfo.getPrice1();
            priceInfo.getPrice2();
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Writer

package threadTest.reentrantReadWriteLockTest;

public class Writer implements Runnable {
    private PricesInfo pricesInfo;

    public Writer(PricesInfo pricesInfo) {
        this.pricesInfo = pricesInfo;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            pricesInfo.setPrices((i+1)* 10, (i+1) * 100);
            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

main函数

package threadTest.reentrantReadWriteLockTest;

public class App1 {
    public static void main(String[] args) {
        PricesInfo pricesInfo = new PricesInfo();
        Reader[] readers = new Reader[5];
        Thread[] threadsReader = new Thread[5];
        for (int i = 0; i < 5; i++) {
            readers[i] = new Reader(pricesInfo);
            threadsReader[i] = new Thread(readers[i]);
        }
        Writer writer = new Writer(pricesInfo);
        Thread threadWriter = new Thread(writer);
        for (int i = 0; i < 5; i++) {
            threadsReader[i].start();
        }
        threadWriter.start();
    }
}

结果如下

使用ReentrantReadWriteLock,同时可以有多个线程执行读操作,但只有一个线程可以执行写操作

时间: 2024-08-08 01:27:16

ReentrantReadWriteLock锁例子的相关文章

Java多线程可重入锁例子解析

"可重入锁"的概念是:自己可以再次获得自己的内部锁.比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁. class sysTest{ synchronized void test1(String str){ System.out.println(str+"1"); test2(str); System.out.println("end" + str); }

java并发 lock锁

Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题将在下面进行阐述.本文先从synchronized的缺陷讲起,然后再讲述java.util.concurrent.locks包

05 JDK1.5 Lock锁

一.synchronized的再次讨论 使用synchronized关键字来标记一个方法或者代码块,当某个线程调用该对象的synchronized方法或者访问synchronized代码块时, 这个线程便获得了该对象的锁,其他线程暂时无法访问这个方法,只有等待这个方法执行完毕或者代码块执行完毕,这个线程才会释放该对象的锁,其他线程才能执行这个方法或者代码块. synchronized 方法: public synchronized type function (... ...); synchro

mysql锁

锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁问题,以及解决MySQL锁问题的一些方法或建议. MySQL锁概述 相对其他数据库而言,MySQL的锁机制比较简单,其最显著

MySQL详解--锁

来源:http://blog.csdn.net/xifeijian/article/details/20313977#t4 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保证数据并发访问的一致性.有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素.从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂.本章我们着重讨论MySQL锁机制的特点,常见的锁

Mysql InnoDB行锁实现方式

InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能.下面通过一些实际例子来加以说明. (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行锁. 在如表20-9所示的例子中,开始

Java学习(十一):Java锁Synchronized,对象锁和类锁举例

Java的锁分为对象锁和类锁. 1. 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内针对该对象的操作只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 2. 然而,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块. 3. 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对该object中所有其它sync

MySQL- InnoDB锁机制

InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识,然后详细讨论InnoDB的锁问题. 背景知识 事务(Transaction)及其ACID属性 事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性. 原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行. 一致性

Mysql InnoDB行锁实现方式(转)

Mysql InnoDB行锁实现方式 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点MySQL与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的.InnoDB这种行锁实现特点意味着:只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁! 在实际应用中,要特别注意InnoDB行锁的这一特性,不然的话,可能导致大量的锁冲突,从而影响并发性能.下面通过一些实际例子来加以说明. (1)在不通过索引条件查询的时候,InnoDB确实使用的是表锁,而不是行