使用读写锁实现同步数据访问

  锁机制最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock。这个类有两个锁,一个是读操作锁,另一个是写操作锁。使用读操作锁时可以允许多个线程同时访问,但是使用写操作锁时只允许一个线程进行。在一个线程执行写操作时,其他线程不能够执行读操作。

  下面我们将通过范例学习如何使用ReadWriteLock接口编写程序。这个范例将使用ReadWriteLock接口控制对价格对象的访问,价格对象存储了两个产品的价格。

1. 创建一个价格信息类PricesInfo,并且存放两个产品的价格。

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

public class PricesInfo {
    //两个价格
    private double price1;
    private double price2;
    //声明读写锁ReadWriteLock对象lock
    private ReadWriteLock lock;
    public PricesInfo(){
        price1 = 1.0;
        price2 = 2.0;
        lock = new ReentrantReadWriteLock();
    }

    public double getPrice1(){
        lock.readLock().lock();
        double value = price1;
        lock.readLock().unlock();
        return value;
    }

    public double getPrice2()
    {
        lock.readLock().lock();
        double value = price2;
        lock.readLock().unlock();
        return value;
    }

    public void setPrices(double price1, double price2){
        lock.writeLock().lock();
        this.price1 = price1;
        this.price2 = price2;
        lock.writeLock().unlock();
    }

}

2. 创建读取类Reader,它实现了Runnable接口。

public class Reader implements Runnable {
    private PricesInfo pricesInfo;
    public Reader(PricesInfo pricesInfo){
        this.pricesInfo = pricesInfo;
    }
    @Override
    public void run() {
        // 循环读取连个价格10次
        for(int i=0;i<10;i++){
            System.out.printf("%s: Price1: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice1());
            System.out.printf("%s: Price2: %f\n", Thread.currentThread().getName(), pricesInfo.getPrice2());
        }

    }

}

3. 创建写入类Writer,它实现了Runnable接口。

public class Writer implements Runnable {
    private PricesInfo pricesInfo;
    public Writer(PricesInfo pricesInfo){
        this.pricesInfo = pricesInfo;
    }
    @Override
    public void run() {
        // 循环修改两个价格3次
        try {
            for(int i=0;i<3;i++){
                System.out.printf("Writer: Attempt to modify the prices.\n");
                pricesInfo.setPrices(Math.random()*10, Math.random()*8);
                System.out.println("Writer: Prices have been modified.");
                Thread.sleep(2);
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

4. 创建范例的主类Main

public class Main {

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

5. 程序运行结果如下

Thread-1: Price1: 1.000000
Thread-4: Price1: 1.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-0: Price1: 1.000000
Thread-0: Price2: 2.000000
Thread-2: Price1: 1.000000
Thread-2: Price2: 2.000000
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-3: Price1: 1.000000
Thread-3: Price2: 4.840562
Thread-1: Price2: 2.000000
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Thread-1: Price1: 6.220535
Thread-1: Price2: 4.840562
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-4: Price2: 2.000000
Thread-4: Price1: 5.640719
Thread-4: Price2: 1.872038
Thread-4: Price1: 5.640719
Thread-4: Price2: 1.872038
Thread-2: Price1: 6.220535
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-2: Price1: 5.640719
Thread-2: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Thread-3: Price1: 5.640719
Thread-3: Price2: 1.872038
Writer: Attempt to modify the prices.
Writer: Prices have been modified.
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
Thread-4: Price1: 5.491746
Thread-4: Price2: 2.729420
时间: 2024-10-13 10:08:54

使用读写锁实现同步数据访问的相关文章

Java并发学习之十五——使用读写锁同步数据访问

本文是学习网络上的文章时的总结,感谢大家无私的分享. 读写锁重要的是写锁的使用,只用一个入口. 下面是读写锁使用的例子 package chapter2; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class PricesInfo { private int price1; private int price2;

比较synchronized和读写锁

一.科普定义 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用,在这就不多说只做几点归纳: Java提供这个关键字,为防止资源冲突提供的内置支持.当任务执行到被synchronized保护的代码片段的时候,它检查锁是否可用,然后获取锁,执行代码,释放锁. 常用这个关键字可以修饰成员方法和代码块 2)读写锁 我们对数据的操作无非两种:“读”和“写”,试想一个这样的

读写锁————用互斥量和条件变量模拟

一. 读写锁 在多线程环境下为了防止对临界资源访问的冲突我们往往会在线程函数中加入互斥锁来完成线程间的互斥:但是,在有些情况下,互斥锁mutex并不是那么高效,比如当要对一块缓冲区进行读写操作的时候,因为读的需要比写入修改的需要要多,读取数据并不会修改缓冲区的数据个数或者内容,如果要使用互斥锁就会耗费额外的时间,每一次读取都要争夺锁资源挂起等待,因此就可以使用另外一种锁机制----读写锁. 有读写锁的存在当然就会有读者和写者,也就是多个线程,但是它们之间的相互关系和mutex锁中有所不同: 当读

ReentrantReadWriteLock读写锁详解

一.读写锁简介 现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁.在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源:但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了. 针对这种场景,JAVA的并发包提供了读写锁ReentrantReadWriteLock,它表示两个锁,一个是读操作相关的锁,称为共享锁:一个是写相关的锁,称为排他锁,描述如下: 线程进入读锁的前提条件: 没有其他线程的写锁, 没

数据库读写锁的实现(C++)

一.基本概念 在数据库中,对某数据的两个基本操作为写和读,分布有两种锁控制:排它锁(X锁).共享锁(S锁). 排它锁(x锁):若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁: 一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁. 共享锁(s锁):若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁: 一般要求在读取数据前要向该数据加共享锁, 所以共享锁又称读锁. 程序所收到的请求包括以下五种:Start.End.X

java并发锁ReentrantReadWriteLock读写锁源码分析

1.ReentrantReadWriterLock基础 所谓读写锁,是对访问资源共享锁和排斥锁,一般的重入性语义为 如果对资源加了写锁,其他线程无法再获得写锁与读锁,但是持有写锁的线程,可以对资源加读锁(锁降级):如果一个线程对资源加了读锁,其他线程可以继续加读锁. java.util.concurrent.locks中关于多写锁的接口:ReadWriteLock public interface ReadWriteLock { /** * Returns the lock used for r

ReadWriteLock: 读写锁

ReadWriteLock: 读写锁 ReadWriteLock: JDK1.5提供的读写分离锁,采用读写锁分离可以有效帮助减少锁竞争. 特点: 1).使用读写锁.当线程只进行读操作时,可以允许多个线程同时读 2).写写操作,读写操作间依然需要相互等待和持有锁. 一).使用读写锁与使用重入锁进行读读写操作 开启200个线程,测试读写锁和重入锁的读效率. 使用重入锁进行读写操作:ReentrantLock_Rw import java.util.concurrent.locks.Reentrant

java读写锁实现数据同步访问

锁机制最大的改进之一就是ReadWriteLock接口和它的唯一实现类ReentrantReadWriteLock.这个类有两个锁,一个是读操作锁,另一个是写操作锁.使用读操作锁时可以允许多个线程同时访问,但是使用写操作锁时只允许一个线程进行.在一个线程执行写操作时,其他线程不能够执行读操作. 下面我们将通过范例学习如何使用ReadWriteLock接口编写程序.这个范例将使用ReadWriteLock接口控制对价格对象的访问,价格对象存储了两个产品的价格. 1. 创建一个价格信息类Prices

锁,同步,可重入锁,读写锁(转)

1.synchronized 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility). 1.1 原子性 原子性意味着个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护.从而防止多个线程在更新共享状态时相互冲突. 1.2 可见性 可见性则更为微妙,它要对付内存缓存和编译器优化的各种反常行为.它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的 . 作用: