3

I'm currently reviewing design patterns. I came across this one Multiton, but I find it difficult to think of a good real-worlds usage example.

So what's the main field of application for the strengths of Multiton pattern?

4

5 回答 5

5
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);

这是多音,一个真实的例子

于 2012-05-09T13:08:56.693 回答
3

Multiton是一种设计模式,它将确保在多线程环境中只为 Key 创建一个对象。因此,如果多个线程尝试传递相同的密钥,则该密钥应该获得相同的对象(锁定对象)。可能我们称它为基于键的单例。

如果我们在整个系统中只有一个锁对象;那么它singleTon适用于您的应用程序。但是这里有多个锁对象;并且每个对象都用一个键映射。

一个例子是;假设有多个会议,并且您希望允许会议的呼叫者一个一个加入(以计算会议中呼叫者的数量)(每个会议对象同步)及其各自的会议 ID。如果我有单例对象,那么即使来自不同会议的呼叫者也会被阻止。所以我需要为每个会议锁定。

所以会议锁对象应该是根据会议ID创建的;并且当多个线程尝试使用相同的会议 ID(多键)访问相同的会议对象时,最终应该在系统中同步。这样如果两个呼叫者同时拨打同一个会议,就会同步。

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];
    }
}
于 2015-03-17T07:41:54.243 回答
1

另一个例子:

假设您有一些监控摄像头,每个摄像头可以有一个且只有一个控制器。

在这种情况下,您应该获得相机类 multiton。它有一个包含<key, camera>对的哈希映射。喜欢:

    public sealed class Camera
    {
    static Dictionary<int, Camera> _cameras = new Dictionary<int, Camera>();
    static object _lock = new object();

    private Camera() 
    {
        HardwareId = Guid.NewGuid();
    }

    public static Camera GetCamera(int cameraCode)
    {
        lock (_lock)
        {
            if (!_cameras.ContainsKey(cameraCode)) _cameras.Add(cameraCode, new Camera());
        }
        return _cameras[cameraCode];
    } 

    public Guid HardwareId { get; private set; }
}
于 2017-01-13T18:28:31.323 回答
0

我认为 Java 的例子ScriptEngine就是一个很好的例子:

// For nashorn
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");

// For rhino
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");

Nashorn 和 rhino 都是 (generic)ScriptEngine的,只有参数显示使用了哪个实现。

于 2016-01-21T09:21:25.797 回答
0

只是添加答案,

我正在从 Cracking The Coding Interview 书中创建一个名为 OTHello 的游戏,其中只有两个玩家,一个是白人玩家,另一个是黑人玩家。

所以我有一个 Player 类,每个游戏应该只有两个实例。每个实例应该有黑色或白色。在创建了两个玩家之后,棋盘就像包含所有玩家、硬币、积分、...的类一样,ETC 不应该有更多的玩家打断,所以这种模式会阻止这种情况的发生。

这同样适用于国际象棋,其中一个棋盘类实例中只能有两个玩家类实例。

于 2021-03-06T21:40:45.783 回答