This example demonstrates the uniquenes of a singleton instances across multiple threads. Unlike earlier examples of TRANSIENT and THREAD lifestyle policy - the instances returned within any given thread and any given part access invocation is the same instance.
tutorial/components/singleton:
Demo.java | A component that that established n threads, and makes multiple requests against the internal parts instance. The number of threads and per-thread hits is controlled by respective context values. |
Gizmo.java | A test component we will use as the solution to the demo context criteria. |
DemoTestCase.java | The testcase. |
<component xmlns="dpml:metro" class="org.acme.Demo" name="demo"> <context> <entry key="threadCount" value="3"/> <entry key="accessCount" value="2"/> </context> <parts> <component key="gizmo" type="org.acme.Gizmo" lifestyle="singleton"/> </parts> </component>
The following debug level logging illustrates the thread name and resolved instance. Analysis of the results demonstrates the resolution of the same instance irrespective of request and/or thread.
test: [junit] Executing forked test. [junit] Running org.acme.test.DemoTestCase [junit] [13279] [INFO ] (demo): gizmo (Thread[0,5,main]) [3916915] [junit] [13279] [INFO ] (demo): gizmo (Thread[2,5,main]) [3916915] [junit] [13279] [INFO ] (demo): gizmo (Thread[1,5,main]) [3916915] [junit] [13279] [INFO ] (demo): gizmo (Thread[1,5,main]) [3916915] [junit] [13279] [INFO ] (demo): gizmo (Thread[0,5,main]) [3916915] [junit] [13279] [INFO ] (demo): gizmo (Thread[2,5,main]) [3916915] [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.891 sec
Components assiated with a singleton sifestyle are shared across thread boundaries and as such need to deal with schronization concerns when managing internal state.