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 }