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

锁机制最大的改进之一就是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-12-29 11:15:37

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

Java读-写锁

显示锁 在java5.0之前,在协调共享对象访问时可以使用的机制只有synchronized和volatile.java5.0增加了一种新的机制:ReentrantLock.ReentrantLock并不是一种替代内置锁的方法,而是当内置锁不适用时,作为一种可选择的高级功能.与内置锁不同的是Lock提供了一个无条件的.可轮询的.定时的以及可中断的锁获取操作,所有加锁和解锁都是显示的.在Lock的实现中必须提供与内部锁相同的内存可见性语义. /**Lock接口*/ public interface

线程同步——用户模式下线程同步——Slim读写锁实现线程同步

1 //Slim读/写锁实现线程同步 2 SRWlock 的目的和关键段相同:对同一资源进行保护,不让其它线程访问. 3 但是,与关键段不同的是,SRWlock允许我们区分哪些想要读取资源的线程(读取者线程) 4 和哪些想要更新资源值的线程(写入者线程).让所有读取者资源在同一时刻访问共享资源应该是 5 可行的,这是因为仅仅读取资源并不存在破坏数据的风险.只有当写入者线程想要对资源进行更新时才需要同步. 6 这种情况下,写入者线程应该独占资源访问权:任何线程,无论是读取还是写入者线程,都不许访问

Java读写锁(ReentrantReadWriteLock)学习

什么是读写锁 平时,我们常见的synchronized和Reentrantlock基本上都是排他锁,这些锁在同一时刻只允许一个线程进行访问,哪怕是读操作.而读写锁是维护了一对锁(一个读锁和一个写锁),通过分离读锁和写锁,使得同一时刻可以允许多个读线程访问,但是在写线程进行访问时,所有的读线程和其他写线程均被阻塞. 读写锁的优点 1. 简化了读写交互场景编程的复杂度: 在常见的开发中,我们经常会定义一个共享的用作缓存的数据结构:比如一个大Map,缓存全部的城市Id和城市name对应关系.这个大Ma

Java多线程学习笔记——从Java JVM对多线程数据同步的一些理解

   我们知道在多线程编程中,我们很大的一部分内容是为了解决线程间的资源同步问题和线程间共同协作解决问题.线程间的同步,通俗我们理解为僧多粥少,在粥有限情况下,我们怎么去防止大家有秩序的喝到粥,不至于哄抢都没得喝.线程讲协作,我们可以理解为我们在医院看病的时候,我们要先挂号,才能看病.现在医院有很多病人排队,怎么协调病人都有秩序的先挂号,后看病.本篇文章的重点不在此,也不是在此一下子能分析完,我们先从Java JVM的角度来理解多线程的一些方面. 我们知道多线程间的数据同步,我们是通过加锁的操作

Java读写锁,多线程环境下提升效率

读写锁 package cn.sniper.thread.lock; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; public class Cache {

Linux:使用读写锁使线程同步

基础与控制原语 读写锁 与互斥量类似,但读写锁允许更高的并行性.其特性为:写独占,读共享. 读写锁状态: 一把读写锁具备三种状态: 1. 读模式下加锁状态 (读锁) 2. 写模式下加锁状态 (写锁) 3. 不加锁状态 读写锁特性:     读写锁是"写模式加锁"时, 解锁前,所有对该锁加锁的线程都会被阻塞. 读写锁是"读模式加锁"时, 如果线程以读模式对其加锁会成功:如果线程以写模式加锁会阻塞. 读写锁是"读模式加锁"时, 既有试图以写模式加锁的

[图解Java]读写锁ReentrantReadWriteLock

图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWriteLock 0. demo 我先给出一个demo, 这样大家就可以根据我给的这段代码, 边调试边看源码了. 还是那句话: 注意"My" , 我把ReentrantReadWriteLock类 改名为了 "MyReentrantReadWriteLock"类 , &q

使用读写锁实现线程同步

简介: 读写锁与互斥量类似,但读写锁允许更高的并行性.其特性为:写独占,读共享. 读写锁特性: 读写锁是"写模式加锁"时,解锁前,所有对该锁加锁的线程都会被阻塞. 读写锁是"读模式加锁"时,如果线程以读模式对其加锁会成功.如果线程以写模式加锁会阻塞. 读写锁是"读模式加锁"时,如果有另外线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求长期阻塞: 读写锁非常适合于对数据结构读的次数远大于写

Java读Exlcel表格数据

1.    了解Excel相关概念 Excel文件有两种格式,文件后缀为.xls的为excel2003及以前版本,文件后缀为.xlsx的为excel2007及以后版本.不同的版本,所使用的API不一样. 一个Excel文件对应一个工作簿(Workbook),一个workbook可以有多个工作表(Sheet)组成,一个sheet由多个单元格(cell)组成.这些单元格分成M行(row).N列(Column)组成.列用大写英文字母表示,从A开始到Z共26列,然后再从AA到AZ又26列,再从BA到BZ