【1月31日】并发(四):活跃度与性能

SynchronizedFactorizer.class

package com.tree.thread;

import java.math.BigInteger;

public class SynchronizedFactorizer implements Servlet {
	private BigInteger lastNumber;
	private BigInteger[] lastFactors;
	
	public synchronized void service(ServletRequest req,ServletResponse resp){
		BigInteger i = extractFromRequest(req);
		if(i.equals(lastNumber)){encodeIntoResponse(resp,factors);}
		else{
			BigInteger[] factors = factor(i);
			lastNumber = i;
			lastFactors = factors;
			encodeIntoResponse(resp,factors);
		}
	
	}

}


CachedFactorizer.class

package com.tree.thread;

import java.math.BigInteger;

public class CachedFactorizer implements Servlet {
	private BigInteger lastNumber;
	private BigInteger[] lastFactors;
	private long hits;
	private long cacheHits;
	
	public synchronized long getHits(){return hits;}
	public synchronized double getCacheHitRatio(){
		return (double)cacheHits/(double)hits;
	}
	
	public void service(ServletRequest req,ServletResponse resp){
		BigInteger i = extractFromRequest(req);
		BigInteger[] factors = null;
		synchronized (this){
			++hits;
			if(i.equals(lastNumber)){
				++cacheHits;
				factors = lastFactors.clone();
			}
		}
		if (factors == null){
			factors = factor(i);
			synchronized(this){
				lastNumber = i;
				lastFactors = factors.clone();
			}
		}
		
		encodeIntoResponse(resp,factors);
	}

}


 

SynchronizedFactorizer中,将service方法声明为synchronized,所以在同一个时间中只有一个线程可以访问service方法—这确保了线程的安全性,但是方式过于极端。

如果同一时间只有一个线程可以访问到,那么进行并发编程又有什么意义呢?就好像是拿到驾照,为了安全,只让你开玩具车;那么拿到驾照又有什么意义呢?

在这种情况下,如果Servlet正在处理一个大数的因数分解,那么在它可以处理一个新的运算开始前,其他用户必须等待,直到当前的请求完成。此运行方式描述为弱并发(poor concurrency):限制并发调用数量的,并非并发可用的处理器资源,而是程序自身的结构。一个可行的策略是:通过缩小synchronized块的范围来维护线程安全性的同时,提供并发的性能。CachedFactorizer重新构造了Servlet。第一个synchronized块保护着检查再运行的操作以检查我们是否可以返回缓存的结果;另一个synchronized缓存了number和factors的同步更新。

决定synchronized块的大小需要权衡各种设计的要求,包括安全性(最重要的!)、简单性和性能。通常简单性和性能之间是相互牵制的(类似于功的黄金定律)。实现一个同步策略时,不要过早地为了性能而牺牲简单性(这是对安全性潜在的威胁)。当使用锁的时候,应该清楚块中的代码的功能,以及它的执行过程中是否会很耗时。无论是作运算密集型的操作,还是执行一个可能存在潜在阻塞的操作,如果线程长时间的占用锁,就会引发活跃度与性能风险的问题。有些耗时的操作,如网络或控制台I/O,难以快速完成。执行这些操作期间不要占用锁。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值