Jump to content

Talk:Multiton pattern

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

Multiton an Antipattern? Please explain here

[edit]

Pending further discussion here, I removed a strange assertion that multiton is viewed as an antipattern by "advocates of dependency injection". I for one often advocate dependency injection, while also often using multiton (albeit not with statics) on the same project e.g. when deserializing some richly interelated data that had to pass through some intermediate format that had little direct ability to express relationships. These days, relational data passing through an XML format is a common example, since XML expresses hierarchy only while relational supports more general network graphs that may need to be reassembled by keying off instance IDs. If someone wants to put it back, please explain here first so we can discuss. Bmord (talk) 20:07, 7 January 2010 (UTC)[reply]

Multiton = Flyweight?

[edit]

The quote within this 'Multiton' article currently states: "multiton does not appear in Design Patterns, the highly-regarded object-oriented programming text book". But it actually does appear in the GoF book under then name "Flyweight pattern" (http://wiki.riteme.site/wiki/Flyweight_pattern). I believe that these articles should be merged, and if not merged, then at least cross reference each other. Another identical concept by yet another name is 'Hash consing' (http://wiki.riteme.site/wiki/Hash_consing), but at least the Flyweight pattern article and the Hash consing articles do cross-link to each other. This 'Multiton' article should be brought into the loop as well, and the sentence stating that 'Multiton' does not appear in the GoF should be corrected to state that it *does*, but under the name "Flyweight pattern". - MR 2010 0408 —Preceding unsigned comment added by 72.229.25.188 (talk) 12:16, 8 April 2010 (UTC)[reply]

Agreed: They seem to be identical. Compare the code samples. The flyweight pattern's example is a little more elaborate, but I see nothing about the Multiton that would preclude it from being called a flyweight nor vice versa.
Disagreed: In my opinion they are not equal, Multiton is a way that you can achieve Flyweight, but you can also share something by Singleton or Static Instance. Probably you can say Multiton is a kind of Flyweight but Flyweight is not equal to Multiton. — Preceding unsigned comment added by Benbai123 (talkcontribs) 02:41, 8 July 2014 (UTC)[reply]
Disagreed: In my view this could be more closely related to a proxy, as you can interface with a shared set of data through separate instance of the access container or through subclasses of the container. By this reasoning you are acting on the data by proxy. Each access container instance can have separate instance data to manipulate the held data by it isn't really an instance of the held data which the Singleton pattern is, and the Multiton pattern (by name only) implies that each access container instance is an instance of the data.
TL:DR The access container is a has-a relationship with the held data and acts on it via proxy. Whereas the N*gleton pattern prescribes or implies an is-a relationship. — Preceding unsigned comment added by 24.111.219.47 (talk) 20:20, 5 November 2014 (UTC)[reply]
Disagreed: The multiton pattern is about the creation of object instances (or rather reusing an existing instance completely), whereas the flyweight pattern aims at reducing the memory footprint among multiple instance of objects by having them reference common information in a single location. Thus in flyweight, the actual object only contains the state that makes it different from other instance and common content is located in another object. Please note that flyweight does not impose that common content is the same among all instances of the flyweight class. It is the ratio of #ofFlyweightObjects (usually many) to #ofCommonStateObjects (usually few) that results in the memory reduction. — Preceding unsigned comment added by 153.96.12.26 (talk) 12:57, 10 March 2016 (UTC)[reply]

NOT double-checked locking

[edit]

The example code is not vulnerable to the double-checked locking anti-pattern. I have updated the double-checked locking page to make the problem more clear.

Right: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, example 2. Pavel Vozenilek 22:16, 19 December 2005 (UTC)[reply]
That's correct; the example code bears the full cost of synchronization - what the double-checked locking [anti-]pattern set out to avoid. 71.253.235.250 01:44, 6 April 2006 (UTC)[reply]
I think most relevant part of the explanation for this on http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html is under the heading "Double-Checked Locking Immutable Objects". I (personally) find that a lot of the examples up till then can leave the reader scratching their head and saying "Huh, this thing on wikipedia looks a lot like the examples of how to do it wrong".
I was still hesitant to believe that all the edge cases were taken care of in the java example with double-checked locking (like, surely the example didn't take into account concurrent resizing of the hashmap correctly?), so I also wrote a quick little test that I'll share here in case anyone else defaults to the I-don't-believe-it-till-I-see-it attitude with threading:
public class FooMultiton {
	private static final Map<Object,FooMultiton>	instances	= new HashMap<Object,FooMultiton>();
	
	private FooMultiton() {
		n.incrementAndGet();
	}
	public static final AtomicInteger n; static { n = new AtomicInteger(); }
	
	public static FooMultiton getInstance(Object key) {
		// Our "per key" singleton
		FooMultiton instance = instances.get(key);
		
		// if the instance has never been created ...
		if (instance == null) {
			synchronized (instances) {
				// Check again, after having acquired the lock to make sure 
				// the instance was not created meanwhile by another thread
				instance = instances.get(key);
				
				if (instance == null) {
					// Lazily create instance
					instance = new	 FooMultiton();
					
					// Add it to map   
					instances.put(key, instance);
				}
			}
		}
		return instance;
	}
	
	private static class Poke implements Runnable {
		public void run() {
			for (int i = 0; i < 10000000; i++) {
				FooMultiton.getInstance(i);
			}
		}
	}
	
	public static void main(String... args) throws InterruptedException {
		long tstart = System.currentTimeMillis();
		
		Thread[] threads = new Thread[4];
		
		for (int i = 0; i < threads.length; i++)
			threads[i] = new Thread(new Poke());

		for (int i = 0; i < threads.length; i++)
			threads[i].start();
		
		for (int i = 0; i < threads.length; i++)
			threads[i].join();
		
		long tend = System.currentTimeMillis();
		System.out.println("Created "+FooMultiton.n.get()+" instances.");
		System.out.println("Took "+(tend - tstart)+" ms.");
	}
}
This example code demonstrates that the example does in fact work. I also found the double-checked locking example to run about twice as fast as the more completely synchronized method, for what it's worth (though of course YMMV as that statement comes from an extremely narrow set of circumstances).
Incidentally, I find it odd that Java constructor visibility is noted to be okay at protected or default visibility. While that technically won't screw with the getInstance method since the map is private, I think it would be at odds with the basic point of the multiton pattern to allow creation of objects of your multiton class that aren't tracked as part of the multiton pattern, so I'm not sure why that comment is there. (The comment has significance in indicating the irrelevance of constructor visibility to the effectiveness of double-checked-locking, but that's not the main point of this article.) -- Heavenlyhash (talk) 21:01, 24 June 2011 (UTC)[reply]
I think that regardless of double-locking memory visibility issue, there is a bug here - get on map is called without holding a lock, where possibly entire map is being rehashed as effect of put from another thread. I don't think that you can rely on every java implementation to have fully safe get in presence of put/rehashing happening at very same time. Artur Biesiadowski (talk) 16:02, 12 September 2011 (UTC)[reply]
I agree: a better code sample would use a ReadWriteLock. Also the other code samples should use similar locking idioms now only the C# code is thread-safe while the others aren't (notably C++). 195.81.168.130 (talk) 14:52, 7 May 2012 (UTC)[reply]

Please discuss changes here first

[edit]

For the second time I have had to remove incorrect commentary on this subject. Please add discussion here if you have questions.

Dubwai 15:52, 19 June 2006 (UTC)[reply]

Multiton = Singleton Collection?

[edit]

How does the Multiton differ from a Singleton Collection? Basically, there's one collection, instead of one object. Perhaps this is why the GoF mentioned it only as a footnote to the Singleton?

Also, I see the lock in the C# example, but I thought that static variables were guaranteed thread-safe. Besides wasting clock cycles, what does the lock buy you?

Answered my own question on the second part via this thread: http://support.microsoft.com/kb/816161. It seems the lock isn't used to ensure thread-safety, so much as it is used to prevent another thread from seeing a static object in an invalid state. It's unclear if seeing this invalid state would result in an exception or not. For anyone else out there confused by the common mantra of "Any shared member variables or functions are thread-safe..." from MSDN articles, this means only that MS has made their shared members thread-safe, not that shared members or methods are inherently thread-safe. Wish this had been stated as clearly in the article here.

—Preceding unsigned comment added by KnockNrod (talkcontribs) 16:07, 21 September 2010 (UTC)[reply]

There appears to be an error in the Java listing using locks. The read and write locks should be lock()'ed *outside* the try blocks. Otherwise the if the locks cannot be acquired (due to e.g. InterruptedException) then the finally block will try to release a lock even though it was never acquired. —Preceding unsigned comment added by 65.116.116.6 (talk) 18:27, 6 December 2010 (UTC)[reply]

Remove most of these languages

[edit]

Shouldn't all these examples be replaced by just one? Then put the rest in wikibooks. — Preceding unsigned comment added by 70.173.192.81 (talk) 19:05, 15 September 2013 (UTC)[reply]

Contstructor and clone

[edit]

Hello, I don't want to change it right away because i'm not sure if i'm right and the php version won't work in the way i see it. But i have the gang of four book right before me and i'm a bit curious if there's a reason that not all constructors are protected. I mean: singletons with a public constructor are kind of useless, because you can't be sure that there's really only 1 instance (or 1 instance for a key in the case of a multiton). The most accurate example seems to be the c++ version because it also declares the copyconstructor as private. So is there anything against making the map and constructors protected? - public constructors + public copyconstructors / clone methods can be used to bypass the registry - protected - you are able to define subclasses of the multiton The php example won't work with protected methods out of the box because of the reflectionclass. Anyone with some good ideas? --DarkXTC90 (talk) 17:28, 6 February 2014 (UTC)[reply]