《并发编程》--18.Java层锁的优化

1 减少锁持有时间

public synchronized void syncMethod(){ 
 	othercode1(); 
 	mutextMethod(); 
 	othercode2(); 
 }
像上述代码这样,在进入方法前就要得到锁,其他线程就要在外面等待。
这里优化的一点在于,要减少其他线程等待的时间,所以,只用在有线程安全要求的程序上加锁

public void syncMethod(){ 
 	othercode1(); 
 	synchronized(this){
 		mutextMethod(); 
 	}
 	othercode2(); 
 }
2 减小锁粒度
将大对象(这个对象可能会被很多线程访问),拆成小对象,大大增加并行度,降低锁竞争。降低了锁的竞争,偏向锁,轻量级锁成功率才会提高。
最最典型的减小锁粒度的案例就是ConcurrentHashMap。
3 锁分离
最常见的锁分离就是读写锁ReadWriteLock,根据功能进行分离成读锁和写锁,这样读读不互斥,读写互斥,写写互斥,即保证了线程安全,又提高了性能。
读写分离思想可以延伸,只要操作互不影响,锁就可以分离。
比如LinkedBlockingQueue 详情查看    《并发编程》--17.BlockingQueue解析

4 锁粗化
通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能尽早的获得资源执行任务。但是,凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化 。
举个例子:

public void demoMethod(){ 
 synchronized(lock){ 
 	//do sth. 
     } 
       //做其他不需要的同步的工作,但能很快执行完毕 
       synchronized(lock){ 
       //do sth. 
     } 
 }
这种情况,根据锁粗化的思想,应该合并
public void demoMethod(){ 
 	//整合成一次锁请求 
 	synchronized(lock){ 
 	//do sth. 
	 //做其他不需要的同步的工作,但能很快执行完毕 
     }
 }
public void demoMethod(){ 
 	//整合成一次锁请求 
        synchronized(lock){ 
 	//do sth. 
 	//做其他不需要的同步的工作,但能很快执行完毕 
     }
 }
当然这是有前提的,前提就是中间的那些不需要同步的工作是很快执行完成的。
再举一个极端的例子:
for(int i=0;i<CIRCLE;i++){ 
	 synchronized(lock){  
 	} 
 }
for(int i=0;i<CIRCLE;i++){ 
 	synchronized(lock){  
        } 
 }
 //在一个循环内不同得获得锁。虽然JDK内部会对这个代码做些优化,但是还不如直接写成
synchronized(lock){ 
 for(int i=0;i<CIRCLE;i++){ 
  
	 } 
 }
synchronized(lock){ 
 for(int i=0;i<CIRCLE;i++){ 
  
 } 
 }

当然如果有需求说,这样的循环太久,需要给其他线程不要等待太久,那只能写成上面那种。如果没有这样类似的需求,还是直接写成下面


那种比较好。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值