博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于读写锁算法的java实现及思考
阅读量:7074 次
发布时间:2019-06-28

本文共 4778 字,大约阅读时间需要 15 分钟。

  问题背景:多个线程对一个共享的资源进行读写访问。写线程之间需要互斥,读线程跟写线程需要互斥,读线程之间不用互斥。

  早些时候听张sir的课,讲述java5中增强并发的功能。用java.util.concurrent.locks中ReadWriteLock 可以轻松解决读写锁问题。我在思考如果没有ReadWriteLock,单靠synchronized可以怎样做呢? 的确,比较麻烦。

  1.结合张sir传授的面向对象的设计思想,首先设计一个业务类Business作为共享资源,封装write跟read方法。

  2.因为write必定互斥,所以直接定义synchronized
  3.read之间不要互斥 所以read 不能直接定义synchronized的 但是 write跟read 需要互斥 如何控制 我想到的一个方法是在read里 加入synchronized(this){} 同时定义readThreads计数器 我试想下会出现下面几种情况:

  read[m]表示某个线程的read方法 

  write[n] 同上

  1>read[m]中执行到synchronized(this){readThreads++;}时 write[n]来了 write[n] 会被自身的synchronized阻塞

  2>read[m]在do something(此时无锁)时 write[n] 来了 因为 readThreads!=0 而被迫wait

  3> 每次read[m]结束时 wait中的write[n]会被notify 但如果发现还有其他的read的话 write[n] 只能无奈地再次wait

  4>当readThreads==0并且调用notifyAll 时 read[m] 和 write[n] 会竞争cpu 如果write[n]再次落败,则会出现1>或3> ; 如果成了,则如下:

  5> 如果write[n] wait中醒来占锁,read[m]被阻塞synchronized(this){readThreads++;}之上

  6>如果被阻塞的write[n]占锁,read[m]被阻塞synchronized(this){readThreads++;}之上

  从以上看来read 和 write 是互斥的

  4.实现细节如下:<如有错误欢迎指出交流>

package communication; import java.util.Random; public class ReadWriteLockTest {
public static void main(String[] args){
final Business business = new Business(); //启动4线程 2读 2写 for(int i=1;i<=2;i++){
new Thread(new Runnable(){
public void run() {
for(int j=1;j<1000;j++){
business.read(); try {
Thread.sleep(900); } catch (InterruptedException e) {
e.printStackTrace(); } } } }).start(); new Thread(new Runnable(){
public void run() {
Random r = new Random(); for(int j=1;j<1000;j++){
int i = r.nextInt(100); business.write(i); try {
Thread.sleep(1000); } catch (InterruptedException e) {
e.printStackTrace(); } } } }).start(); } } } //封装的业务类 class Business{
private int data=0; //共享资源属性 private int readThreads = 0; //读线程数 //private boolean isWriting = false; //是否执行写 后来发现不需要 当write抢占锁时 所有的read 都被挡在synchronized (this){}之上 无机会执行wait public void read(){
synchronized (this) { /*while(isWriting){
try { this.wait(); } catch (InterruptedException e) {
// TODO Auto-generated catch block e.printStackTrace(); } }*/ //readThreads不被锁的话 会出现read和write不互斥的小概率事件 导致线程不安全 readThreads++; } System.out.println(Thread.currentThread().getName()+" read begin"); System.out.println(Thread.currentThread().getName()+" read:"+data); System.out.println(Thread.currentThread().getName()+" read finish"); synchronized (this) {
readThreads--; this.notifyAll(); } } public synchronized void write(int i){
while(readThreads != 0){
//当read 正处于do something状态时 来个write 那就只有等等先了 try {
this.wait(); } catch (InterruptedException e) {
e.printStackTrace(); } } //isWriting = true; System.out.println(Thread.currentThread().getName()+" write start"); data = i; System.out.println(Thread.currentThread().getName()+" write:"+i); System.out.println(Thread.currentThread().getName()+" write over"); //isWriting = false; this.notifyAll(); } }

  思考中:

  5.当读频繁时 readThreads会长时间!= 0 写线程会饿死 这个可以如何解决?

转载于:https://www.cnblogs.com/hottea4Goodspeed/archive/2012/03/06/2381257.html

你可能感兴趣的文章
url请求返回结果测试工具(CURL)
查看>>
虚拟机安装教程
查看>>
java对文件的检索
查看>>
Marquee滚动字幕设置(转)
查看>>
linux系统下调度数据库类型资源库中的kettle job
查看>>
8UFTP
查看>>
VC 2005 解决方案的目录结构设置和管理
查看>>
吾爱论坛浏览器分享
查看>>
java内存模型优化建议
查看>>
解决Ubuntu Kylin 1610安装ANSYS17.2的NVIDIA显卡驱动问题
查看>>
Linux下如何修改Apache根目录
查看>>
JAVA入门[2]-安装Maven
查看>>
什么是回调函数
查看>>
HDU 2588 GCD &amp;&amp; GCD问题总结
查看>>
2015年北京大学软件project学科优秀大学生夏令营上机考试---C:单词翻转面试题...
查看>>
cocos2d-x 3.0的坑有哪些
查看>>
awk条件语句
查看>>
TCP端口状态说明ESTABLISHED、TIME_WAIT
查看>>
the import java.util.* cannot be resolve,怎么解决
查看>>
去哪网实习总结:开发定时任务(JavaWeb)
查看>>