温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

关于读写锁算法的Java实现及思考是怎么样的

发布时间:2021-10-29 10:54:54 来源:亿速云 阅读:133 作者:柒染 栏目:编程语言

本篇文章给大家分享的是有关关于读写锁算法的Java实现及思考是怎么样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

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

早些时候听张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 写线程会饿死 这个可以如何解决?

以上就是关于读写锁算法的Java实现及思考是怎么样的,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI