java怎么写算法_关于读写锁算法的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.实现细节如下:

packagecommunication;

importjava.util.Random;

publicclassReadWriteLockTest {

publicstaticvoidmain(String[] args){

finalBusiness business =newBusiness();

//启动4线程 2读 2写

for(inti=1;i<=2;i++){

newThread(newRunnable(){

publicvoidrun() {

for(intj=1;j<1000;j++){

business.read();

try{

Thread.sleep(900);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

newThread(newRunnable(){

publicvoidrun() {

Random r =newRandom();

for(intj=1;j<1000;j++){

inti = r.nextInt(100);

business.write(i);

try{

Thread.sleep(1000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}

}

}).start();

}

}

}

//封装的业务类

classBusiness{

privateintdata=0;//共享资源属性

privateintreadThreads =0;//读线程数

//private boolean isWriting  = false;

//是否执行写 后来发现不需要 当write抢占锁时 所有的read 都被挡在synchronized (this){}之上 无机会执行wait

publicvoidread(){

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();

}

}

publicsynchronizedvoidwrite(inti){

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 写线程会饿死 这个可以如何解决?

【编辑推荐】

【责任编辑:小林 TEL:(010)68476606】

点赞 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值