文档章节

Java并发编程初级篇(十四):使用读写所实现同步机制

阿拉德大陆的魔法师
 阿拉德大陆的魔法师
发布于 2016/11/25 11:29
字数 939
阅读 16
收藏 0

Java API除了提供Lock()接口之外,还为我们提供了一个读写锁接口ReadWriteLock,使用这个锁的实现类ReentrantReadWriteLock可以让我们把读锁和写锁进行分离,对同步数据进行修改的时候使用写锁,这时候其他需要获取写锁的线程会被挂起,同时使用读锁的线程也会被挂起。而读取数据的时候使用读锁,这时候使用读锁的线程可以并发访问,以提高效率。

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading.
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing.
     */
    Lock writeLock();
}

我们模拟一个修改价格的例子,来看一下读锁与写锁是如何使用的。

创建一个价格类,里面两个商品的价格以及一个读写锁。在修改价格的方法里我们使用写锁,在读取商品价格的方法里我们使用读锁。修改商品价方法休眠两秒来模拟修改价格的过程,并打印修改价格信息。

public class PriceInfo {
    private double price1;
    private double price2;
    private ReadWriteLock lock;

    public PriceInfo() {
        price1 = 1.0;
        price2 = 2.0;
        lock = new ReentrantReadWriteLock();
    }

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

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

    public void setPrice(double price1, double price2) {
        lock.writeLock().lock();
        System.out.printf("Writer: Attemp to modify the price! Price1:%f Price2:%f\n", price1, price2);
        this.price1 = price1;
        this.price2 = price2;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.printf("Writer: Price has been modified: Price1:%f Price2:%f\n", price1, price2);
        lock.writeLock().unlock();
    }
}

创建一个价格修改线程,随机休眠一定时间后修改价格。

public class Writer implements Runnable{
    private PriceInfo priceInfo;

    public Writer(PriceInfo priceInfo) {
        this.priceInfo = priceInfo;
    }

    @Override
    public void run() {
        double price1 = Math.random() * 10;
        double price2 = Math.random() * 8;

        try {
            Thread.sleep((long) (Math.random() * 10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        priceInfo.setPrice(price1, price2);
    }
}

创建一个价格读取线程,每次读取两个商品的价格并打印。

public class Reader implements Runnable {
    private PriceInfo priceInfo;

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

    @Override
    public void run() {
        Date date = new Date();
        System.out.printf("%s: Price1 %f .%s\n",
                Thread.currentThread().getName(), priceInfo.getPrice1(), date);
        System.out.printf("%s: Price2 %f .%s\n",
                Thread.currentThread().getName(), priceInfo.getPrice2(), date);
    }
}

创建主方法类,启动三个价格修改线程。然后每个两秒启动一个线程读取商品价格。

public class Main {
    public static void main(String[] args) {
        PriceInfo priceInfo = new PriceInfo();

        for (int i = 0; i < 3; i++) {
            Thread threadWriter = new Thread(new Writer(priceInfo));
            threadWriter.start();
        }

        while (true) {
            new Thread(new Reader(priceInfo)).start();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

查看控制台日志,每次读取价格都是修改价格之后的新价格,并且在修改价格的2秒内,读取价格线程处于挂起状态。

Thread-3: Price1 1.000000 .Fri Nov 25 11:16:35 CST 2016
Thread-3: Price2 2.000000 .Fri Nov 25 11:16:35 CST 2016
Writer: Attemp to modify the price! Price1:9.655775 Price2:4.031177
Writer: Price has been modified: Price1:9.655775 Price2:4.031177
Thread-4: Price1 9.655775 .Fri Nov 25 11:16:37 CST 2016
Thread-4: Price2 4.031177 .Fri Nov 25 11:16:37 CST 2016
Thread-5: Price1 9.655775 .Fri Nov 25 11:16:39 CST 2016
Thread-5: Price2 4.031177 .Fri Nov 25 11:16:39 CST 2016
Writer: Attemp to modify the price! Price1:2.347803 Price2:2.088409
Writer: Price has been modified: Price1:2.347803 Price2:2.088409
Thread-6: Price1 2.347803 .Fri Nov 25 11:16:41 CST 2016
Thread-6: Price2 2.088409 .Fri Nov 25 11:16:41 CST 2016
Thread-7: Price1 2.347803 .Fri Nov 25 11:16:43 CST 2016
Thread-7: Price2 2.088409 .Fri Nov 25 11:16:43 CST 2016
Writer: Attemp to modify the price! Price1:0.981288 Price2:6.281034
Writer: Price has been modified: Price1:0.981288 Price2:6.281034
Thread-8: Price1 0.981288 .Fri Nov 25 11:16:45 CST 2016
Thread-8: Price2 6.281034 .Fri Nov 25 11:16:45 CST 2016
Thread-9: Price1 0.981288 .Fri Nov 25 11:16:47 CST 2016
Thread-9: Price2 6.281034 .Fri Nov 25 11:16:47 CST 2016
Thread-10: Price1 0.981288 .Fri Nov 25 11:16:49 CST 2016
Thread-10: Price2 6.281034 .Fri Nov 25 11:16:49 CST 2016
Thread-11: Price1 0.981288 .Fri Nov 25 11:16:51 CST 2016
Thread-11: Price2 6.281034 .Fri Nov 25 11:16:51 CST 2016

 

© 著作权归作者所有

共有 人打赏支持
阿拉德大陆的魔法师
粉丝 22
博文 91
码字总数 83019
作品 0
西城
程序员
【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___
05/06
0
0
再有人问你Java内存模型是什么,就把这篇文章发给他。

前几天,发了一篇文章,介绍了一下JVM内存结构、Java内存模型以及Java对象模型之间的区别。有很多小伙伴反馈希望可以深入的讲解下每个知识点。Java内存模型,是这三个知识点当中最晦涩难懂的...

Java架构
07/11
0
0
再有人问你Java内存模型是什么,就把这篇文章发给他

网上有很多关于Java内存模型的文章,在《深入理解Java虚拟机》和《Java并发编程的艺术》等书中也都有关于这个知识点的介绍。但是,很多人读完之后还是搞不清楚,甚至有的人说自己更懵了。本文...

java高级架构牛人
07/04
0
0
读书笔记之《Java并发编程的艺术》-并发编程基础

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
8
面试总结——Java高级工程师(附答案)

面试前面也总结了一和二, 这第三篇可能更偏向于是内心的独白篇和面试技巧总结吧..... 一、独白 之前也面试别人,现在轮到自己找工作,怎么说呢,每个面试官的看法不一样,面试的方式就不一样...

欧阳海阳
07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

弹性工作制的魔咒

简评:你找到了一份完美的工作 —— 可以提前离开公司,还可以在晚上从家里回复邮件。既然如此,你为什么还会有那么强的负罪感呢? 或许是弹性工作制魔咒在作祟。 很多享受弹性工作制的人会始...

极光推送
8分钟前
0
0
KAFKA介绍(分布式架构)

Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语: Kafka将消息以...

明理萝
14分钟前
0
1
os::NodeHandle::subscribe回调函数绑定对象

void Foo::callback(const std_msgs::Empty::ConstPtr& message){}Foo foo_object;ros::Subscriber sub = handle.subscribe("my_topic", 1, &Foo::callback, &foo_object); 参考: ht......

itfanr
16分钟前
0
0
React16.4 开发简书项目 从零基础入门到实战

React16.4 开发简书项目 从零基础入门到实战 关注我的订阅号下载 React16.4 开发简书项目 从零基础入门到实战

蜗牛奔跑
18分钟前
0
0
day57-20180815-流利阅读笔记-待学习

社恐怎么办?这个漫画或许能治愈你 毛西 2018-08-15 1.今日导读 近日,芬兰漫画家卡罗利娜·科尔霍宁创作的绘本《芬兰人的噩梦》在中国大火。一时间书中的主人公马蒂成为了人们茶余饭后热议的...

aibinxiao
22分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部