001 /***************************************************************************** 002 * Copyright (C) PicoContainer Organization. All rights reserved. * 003 * ------------------------------------------------------------------------- * 004 * The software in this package is published under the terms of the BSD * 005 * style license a copy of which has been included with this distribution in * 006 * the LICENSE.txt file. * 007 * * 008 * Original code by * 009 *****************************************************************************/ 010 package org.picocontainer.defaults.issues; 011 012 import static org.junit.Assert.assertTrue; 013 014 import java.util.ArrayList; 015 import java.util.List; 016 017 import org.junit.Test; 018 import org.picocontainer.DefaultPicoContainer; 019 import org.picocontainer.PicoContainer; 020 import org.picocontainer.behaviors.Synchronizing; 021 import org.picocontainer.injectors.ConstructorInjection; 022 023 public final class Issue0199TestCase { 024 025 public static class A { 026 public A(C c) {} 027 } 028 029 public static class B { 030 public B(C c) {} 031 } 032 033 public static class C {} 034 035 final class Runner extends Thread { 036 private final PicoContainer container; 037 private final Object componentKey; 038 private Throwable throwable; 039 private boolean finished; 040 041 Runner(String name, PicoContainer container, Object componentKey) { 042 super(name); 043 this.container = container; 044 this.componentKey = componentKey; 045 } 046 047 public void run() { 048 try { 049 report("Started instantiating " + componentKey.toString()); 050 container.getComponent(componentKey); 051 report("Finished instantiating " + componentKey.toString()); 052 finished = true; 053 } catch (Throwable t) { 054 this.throwable = t; 055 } 056 } 057 058 private void report(String messsage) { 059 System.out.println(getName() + ": " + messsage); 060 } 061 062 public boolean isFinished() { 063 return finished; 064 } 065 066 public Throwable getThrowable() { 067 return throwable; 068 } 069 } 070 071 @Test public void testPicoContainerCausesDeadlock() throws InterruptedException { 072 DefaultPicoContainer container = createContainer(); 073 container.addComponent("A", A.class); 074 container.addComponent("B", B.class); 075 container.addComponent("C", C.class); 076 077 final int THREAD_COUNT = 2; 078 List runnerList = new ArrayList(THREAD_COUNT); 079 080 for (int i = 0; i < THREAD_COUNT; ++i) { 081 Runner runner = new Runner("Runner " + i, container, (i % 2 == 0) ? "A" : "B"); 082 runnerList.add(runner); 083 runner.start(); 084 } 085 086 final long WAIT_TIME = 1000; 087 088 for (int i = 0; i < THREAD_COUNT; ++i) { 089 Runner runner = (Runner) runnerList.get(i); 090 runner.join(WAIT_TIME); 091 assertTrue("Deadlock occurred", runner.isFinished()); 092 } 093 } 094 095 private DefaultPicoContainer createContainer() { 096 return new DefaultPicoContainer( 097 new Synchronizing().wrap(new ConstructorInjection())); 098 } 099 }