public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. }
public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { synchronized (theObjectIwantToSave) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. } }
import java.util.HashMap; import java.util.concurrent.atomic.AtomicInteger; // it is no advantage of using ConcurrentHashMap, since we synchronize access to it // (we need to in order to "get" the lock and increment/decrement it safely) // AtomicInteger is just a mutable int value holder // we don't actually need it to be atomic static final HashMap locks = new HashMap(); public static void saveSomethingImportantToDataBase(Object objectToSave) { AtomicInteger lock; synchronized (locks) { lock = locks.get(objectToSave.getId()); if (lock == null) { lock = new AtomicInteger(1); locks.put(objectToSave.getId(), lock); } else lock.incrementAndGet(); } try { synchronized (lock) { // do synchronized work here (synchronized by objectToSave's id) } } finally { synchronized (locks) { lock.decrementAndGet(); if (lock.get() == 0) locks.remove(id); } } }
public class IdLock { private Object[] locks = new Object[10000]; public IdLock() { for (int i = 0; i < locks.length; i++) { locks[i] = new Object(); } } public Object getLock(int id) { int index = id % locks.length; return locks[index]; }
}
及其用途:
private idLock = new IdLock(); public void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { synchronized (idLock.getLock(theObjectIwantToSave.getId())) { // synchronized work here } }
// there is no synchronized weak hash map, apparently // and Collections.synchronizedMap has no putIfAbsent method, so we use synchronized(locks) down below WeakHashMap locks = new WeakHashMap<>(); public void saveSomethingImportantToDataBase(DatabaseObject objectToSave) { Integer lock; synchronized (locks) { lock = locks.get(objectToSave.getId()); if (lock == null) { lock = new Integer(objectToSave.getId()); locks.put(lock, lock); } } synchronized (lock) { // synchronized work here (synchronized by objectToSave's id) } // no releasing needed, weakref does that for us, we're done! }
public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { synchronized (theObjectIwantToSave) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. } }
private static HashSet isUsed= new HashSet (); public synchronized static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { if(isUsed.contains(theObjectIwantToSave.your_integer_value) != null) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. isUsed.add(theObjectIwantToSave.your_integer_value); } }
public static synchronized void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. }