您的位置:首页 > 大数据

Java并发编程之ReadWriteLock,读取大数据的利器

2017-12-22 13:54 513 查看
现在都是“大数据”时代,大量的用户数据需要处理,如何保证大量数据在多线程下的安全,成了比较重要的问题。
今天要学习的就是java.util.concurrent包下Locks接口的一个实现类,ReadWriteLock,读写锁。

读写锁的出现是为了弥补传统同步方式synchronized的缺憾,使用synchronized同步的方法或语句,当多线程读取一个大数据时,每次只能有一个线程读取,其他线程都得等当前线程读取完才能读,太耗时间。
代码如下:
/**

读写锁 : 在读写大数据时有效提高效率<br>

对数据进行读写时,同时读可以不用同步,同时写、同时读写才用

@author sxzhang

@since 2015/8/21 9:23

*/
public class ReadWriteTest {

public static void main(String[] args) {
final Data data = new Data();
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = data;
System.out.println(threadName + "写入 " + this.data + "完毕 --->");
}

public synchronized void getData() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + "准备读取数据:<---");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName + "读取数据 " + this.data + "完毕 <---");
}

}

</pre><span style="font-size:18px">为了模拟大数据,我们把每次读取的时间延长一些。</span><p></p><p><span style="font-size:18px">运行结果:</span></p><p><img src="[url=http://img.blog.csdn.net/20150821100455408?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" target=_blank>http://img.blog.csdn.net/20150821100455408?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
" alt="" /></p><p><span style="font-size:18px">可以看到,不管每个线程读取数据耗时多长,同时只能有一个线程读取数据,其他数据都被阻塞,等待当前线程结束后才能访问。</span></p><p><span style="font-size:18px"></span></p><p><span style="font-size:18px">而使用读写锁后,多个线程同时读取时,可以并发执行,不会阻塞。</span></p><p><span style="font-size:18px">代码如下:</span></p><p></p><pre name="code" class="java">/**

读写锁 : 在读写大数据时有效提高效率<br>

对数据进行读写时,同时读可以不用同步,同时写、同时读写才用

@author sxzhang

@since 2015/8/21 9:23

*/
public class ReadWriteTest {

public static void main(String[] args) {
final Data1 data = new Data1();
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {[url=mailto:br/>@Override
@Override
data.setData(new Random().nextInt(30));
}
}).start();
}
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {[url=mailto:br/>@Override
@Override
data.getData();
}
}).start();
}
}

}

/**

使用读写锁同步的类<br>

多个线程同时读取时,可以并发执行,不会阻塞

@author sxzhang

*/
class Data1{
private int data; //共享资源
//Creates a new ReentrantReadWriteLock with default (nonfair) ordering properties.
//默认不公平,指的是,阻塞时间长的线程不一定先获取被释放的资源
private ReadWriteLock rwl = new ReentrantReadWriteLock();

public void setData(int data) {
rwl.writeLock().lock(); //記得用完及時釋放锁
try{
String threadName = Thread.currentThread().getName();
System.out.println(threadName + "准备写数据:--->");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.data = data;
System.out.println(threadName + "写入 " + this.data + "完毕 --->");
}finally{
rwl.writeLock().unlock(); //release the writeLock
}
}

public void getData() {
rwl.readLock().lock();
try{
String threadName = Thread.currentThread().getName();
System.out.println(threadName + "准备读取数据:<---");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName + "读取数据 " + this.data + "完毕 <---");
}finally{
rwl.readLock().unlock();
}
}
}
运行结果:

可以看到,线程3、4、5同时读取数据,这样就比synchronized节省不少时间。

要学习java并发编程,java.util.concurrent包下的内容还要好好学习

(学习参考自http://blog.csdn.net/ghsau/article/details/7461369/#comments,谢谢这位前辈)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试相关