【推荐】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
来源:oschina
链接:https://my.oschina.net/u/2633112/blog/794127