关于读写锁算法的Java实现及思考
2012-10-20 16:13
351 查看
问题背景:多个线程对一个共享的资源进行读写访问。写线程之间需要互斥,读线程跟写线程需要互斥,读线程之间不用互斥。
早些时候听张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
同上
1>read[m]中执行到synchronized(this){readThreads++;}时 write
来了 write
会被自身的synchronized阻塞。
2>read[m]在do something(此时无锁)时 write
来了 因为 readThreads!=0 而被迫wait。
3> 每次read[m]结束时 wait中的write
会被notify 但如果发现还有其他的read的话 write
只能无奈地再次wait。
4>当readThreads==0并且调用notifyAll 时 read[m] 和 write
会竞争cpu 如果write
再次落败,则会出现1>或3> ; 如果成了,则如下:
5> 如果write
wait中醒来占锁,read[m]被阻塞synchronized(this){readThreads++;}之上。
6>如果被阻塞的write
占锁,read[m]被阻塞synchronized(this){readThreads++;}之上。
从以上看来read 和 write 是互斥的。
4.实现细节如下:<如有错误欢迎指出交流>
思考中:
5.当读频繁时 readThreads会长时间!= 0 写线程会饿死 这个可以如何解决?
原文链接:http://www.cnblogs.com/hottea4Goodspeed/archive/2012/03/06/2381257.html
早些时候听张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
同上
1>read[m]中执行到synchronized(this){readThreads++;}时 write
来了 write
会被自身的synchronized阻塞。
2>read[m]在do something(此时无锁)时 write
来了 因为 readThreads!=0 而被迫wait。
3> 每次read[m]结束时 wait中的write
会被notify 但如果发现还有其他的read的话 write
只能无奈地再次wait。
4>当readThreads==0并且调用notifyAll 时 read[m] 和 write
会竞争cpu 如果write
再次落败,则会出现1>或3> ; 如果成了,则如下:
5> 如果write
wait中醒来占锁,read[m]被阻塞synchronized(this){readThreads++;}之上。
6>如果被阻塞的write
占锁,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 写线程会饿死 这个可以如何解决?
原文链接:http://www.cnblogs.com/hottea4Goodspeed/archive/2012/03/06/2381257.html
相关文章推荐
- 关于读写锁算法的Java实现及思考
- 关于java实现插入排序的思考
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- java基础——关于异步任务串行执行的思考与实现
- 关于Java泛型实现原理的思考与一般用法示例总结
- Java基本功练习十五(关于对象的思考【ATM机模拟、贷款类、堆栈类、选课类的实现】)
- Java基础之关于几种单例实现的思考
- 关于微软面试题:"四人过桥"问题的思考——“n人过桥”问题的演进(Java实现)
- Java入门:关于Java栈与堆的深入思考
- Java中关于Iterator和Iteratable设计的思考
- 关于Java WebService 的几种实现方式
- 关于Java中Scanner对象的hasNext()方法对实现Readable接口的对象中的read()方法调用的探讨
- 关于Java字符串操作的思考和总结
- 关于一道J笔试或者机试题的Java实现:从键盘输入一串字符,翻转后输出(要求不使用string相关类即对象)
- 关于如何在java中实现中文首字母索引排序的问题
- java中关于目录树的简单实现
- 关于消费者.生产者,缓冲区的简单java实现
- 关于java.util.Random的实现原理详解
- 关于java数组的深度思考
- 关于java socket 关闭的思考.