在两个或多个对象上同步(Java)
我有如下类似的代码:在两个或多个对象上同步(Java),java,object,synchronized,multithreading,Java,Object,Synchronized,Multithreading,我有如下类似的代码: public class Cache{ private final Object lock = new Object(); private HashMap<Integer, TreeMap<Long, Integer>> cache = new HashMap<Integer, TreeMap<Long, Integer>>(); private AtomicLong FREESPACE = new AtomicL
public class Cache{
private final Object lock = new Object();
private HashMap<Integer, TreeMap<Long, Integer>> cache =
new HashMap<Integer, TreeMap<Long, Integer>>();
private AtomicLong FREESPACE = new AtomicLong(102400);
private void putInCache(TreeMap<Long, Integer> tempMap, int fileNr){
int length; //holds the length of data in tempMap
synchronized(lock){
if(checkFreeSpace(length)){
cache.get(fileNr).putAll(tmpMap);
FREESPACE.getAndAdd(-length);
}
}
}
private boolean checkFreeSpace(int length){
while(FREESPACE.get() < length && thereIsSomethingToDelete()){
// deleteSomething returns the length of deleted data or 0 if
// it could not delete anything
FREESPACE.getAndAdd(deleteSomething(length));
}
if(FREESPACE.get() < length) return true;
return false;
}
}
公共类缓存{
私有最终对象锁=新对象();
专用哈希映射缓存=
新的HashMap();
私有原子长自由空间=新原子长(102400);
私有void putInCache(树映射tempMap,int fileNr){
int length;//保存tempMap中数据的长度
已同步(锁定){
如果(选中自由空间(长度)){
cache.get(fileNr).putAll(tmpMap);
自由空间。getAndAdd(-length);
}
}
}
私有布尔校验空间(整数长度){
while(FREESPACE.get(){
//deleteSomething返回已删除数据的长度,如果是,则返回0
//它不能删除任何内容
getAndAdd(deleteSomething(length));
}
if(FREESPACE.get()
putInCache
每秒被大约139个线程调用。我是否可以确保这两个方法将在缓存
和自由空间
上同步?另外,checkFreeSpace()
multi-thread是否安全,即我能否确保一次只调用一次此方法?这段代码的“多线程安全性”可以提高吗?您通常不会对要直接控制访问的字段进行同步。
必须仅从同步块(在同一对象上)内访问要同步访问的字段,才能将其视为线程安全的。您已经在putInCache()
中执行了此操作。
因此,由于
checkFreeSpace()
以非同步方式访问共享状态,因此它不是线程安全的。要完全回答您的问题,您需要显示thereIsSomethingToDelete()和deleteSomething()方法的实现
假设checkFreeSpace是一个公共方法(真的需要吗?),并且是不同步的,那么在putInCache()方法中的同步块运行时,另一个线程可能会调用它。这本身可能不会破坏任何东西,因为checkFreeSpace方法似乎只能增加而不能减少可用空间
更严重的是(代码示例不允许我们确定这一点)如果thereIsSomethingToDelete()和deleteSomething()方法没有使用putInCache()使用的相同对象锁正确同步对缓存对象的访问 如果我将
putInCache()
声明为synchronized
,该怎么办?这会使两种方法“更安全”吗?您需要在字段级别保护访问,这意味着访问这些字段的所有方法都需要在同一个锁对象上同步。简而言之,您还需要在checkFreeSpace()中添加一个同步块。谢谢您的回复。首先,public
不是什么大问题,因为这两个方法只由同一类中的另一个方法调用。至于有一些thingtodelete()
和deleteSomething()
,我实际上没有这些方法。它们的逻辑包含在checkFreeSpace
方法中,但如果我把所有代码都放在这里,那就太混乱了。让我们假设这些方法是正确同步的。对不起,我选择了错误的方法来提问。请看一看编辑后的版本。因此推测putInCache()也不是真正私有的(否则该类实际上如何使用)。然后,我认为该类是线程安全的,因为只有当线程持有putInCache()synchronized块建立的锁时,才能访问可变状态(在该代码中使用AtomicLong
)