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

蓝咒 提交于 2019-12-12 19:43:03

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!