在Java中同步String对象
我有一个webapp,我正在进行一些负载/性能测试,特别是在我们希望有几百个用户访问同一页面并在此页面上每10秒点击一次刷新的功能。我们发现我们可以使用此功能进行改进的一个方面是在一段时间内缓存来自Web服务的响应,因为数据没有变化。
在实现这个基本缓存之后,在一些进一步的测试中,我发现我没有考虑并发线程如何同时访问Cache。我发现在大约100毫秒内,大约有50个线程试图从Cache中获取对象,发现它已经过期,命中Web服务以获取数据,然后将对象放回缓存中。
原始代码看起来像这样:
private SomeData[] getSomeDataByEmail(WebServiceInterface service, String email) { final String key = "Data-" + email; SomeData[] data = (SomeData[]) StaticCache.get(key); if (data == null) { data = service.getSomeDataForEmail(email); StaticCache.set(key, data, CACHE_TIME); } else { logger.debug("getSomeDataForEmail: using cached object"); } return data;}
因此,为了确保在对象key
过期时只有一个线程正在调用Web服务,我认为我需要同步Cache get / set操作,并且似乎使用缓存键是一个很好的候选对象同步(这样,对电子邮件b@b.com的此方法的调用不会被方法调用a@a.com阻止)。
我将方法更新为如下所示:
private SomeData[] getSomeDataByEmail(WebServiceInterface service, String email) { SomeData[] data = null; final String key = "Data-" + email; synchronized(key) { data =(SomeData[]) StaticCache.get(key); if (data == null) { data = service.getSomeDataForEmail(email); StaticCache.set(key, data, CACHE_TIME); } else { logger.debug("getSomeDataForEmail: using cached object"); } } return data;}
我希望在get / set操作周围一次只能看到一个线程进入/退出同步块。
在String对象上同步是否存在问题?我认为缓存键是一个很好的选择,因为它对于操作是唯一的,即使final String key
在方法中声明,我也认为每个线程都会获得对同一个对象的引用,因此会同步单个对象。
我在这做错了什么?
慕尼黑5688855
相关分类