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.