Multiton
- это шаблон проектирования, который гарантирует, что будет создан только один объект для ключа в многопоточной среде. Поэтому, если несколько потоков пытаются передать один и тот же ключ, он должен получить один и тот же объект (объект блокировки) для этого ключа. Может быть, мы называем его синглтоном на основе ключа.
Если у нас есть ТОЛЬКО ОДИН объект блокировки во всей системе; тогда это singleTon
для вашего приложения. Но здесь несколько объектов блокировки; и каждый объект сопоставлен с ключом.
Один из примеров; Предположим, что существует несколько конференций, и вы хотите разрешить присоединение вызывающих абонентов к конференции по одному (для подсчета количества вызывающих абонентов в конференции) (СИНХРОНИЗИРОВАННЫЙ НА КОНФЕРЕНЦ-ОБЪЕКТ) с соответствующим идентификатором conferenceID. Если у меня есть одноэлементный объект, то даже абоненты из другой конференции будут заблокированы. Поэтому мне нужна блокировка для каждой конференции.
Таким образом, объекты блокировки конференции должны создаваться на основе идентификатора конференции; и когда несколько потоков, пытающихся получить доступ к одному и тому же объекту конференции с одним и тем же идентификатором конференции (многотонным ключом), должны завершиться синхронизацией в системе. Таким образом, если два абонента наберут одну и ту же конференцию одновременно, они будут синхронизированы.
class LockByKey {
ObjectForStringKey objHolder = new ObjectForStringKey(100);
public void lockThenWorkForKey (String key) {
synchronized(objHolder.valueOf(key)){
//DoSomeWork
}
}
}
//MultiTon
public final class ObjectForStringKey {
private final Object[] cache;
private final int cacheSize;
final int mask;
public ObjectForStringKey(int size) {
// Find power-of-two sizes best matching arguments
int ssize = 1;
while (ssize < size) {
ssize <<= 1;
}
mask = ssize - 1;
cache = new Object[ssize];
cacheSize = ssize;
//build the Cache
for (int i = 0; i < cacheSize; i++) {
this.cache[i] = new Object();
}
}
public Object valueOf(String key) {
int index = key.hashCode();
return cache[index & mask];
}
}