1 /*************************************************************************************** 2 * Copyright (c) Jonas Bonér, Alexandre Vasseur. All rights reserved. * 3 * http://aspectwerkz.codehaus.org * 4 * ---------------------------------------------------------------------------------- * 5 * The software in this package is published under the terms of the LGPL license * 6 * a copy of which has been included with this distribution in the license.txt file. * 7 **************************************************************************************/ 8 package test.clapp; 9 10 import java.io.File; 11 import java.net.URL; 12 import java.net.URLClassLoader; 13 14 /*** 15 * App loading lots of class in lots of threads <p/>Mandatory args = thread number, loop per thread, 16 * pause between loops <br/>If no args are provided, defaults to 2, 5, 5ms. <br/><br/>Each thread 17 * loop loads DummyClass thru a dedicated URLClassLoader (no parent) at each loop 18 * <br/>test.xmldef.clapp.DummyClass and test.xmldef.clapp.ReentrantDummyClass must be in directory 19 * specified thru -DDummyClass, defaults <i>ASPECTWERKZ_HOME </i>/target/test-classes <br/>During 20 * the DummyClass clinit, another class is loaded thru another URLClassLoader (no parent) 21 * 22 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a> 23 */ 24 public class CrazyClassLoaderApp { 25 private static final String DUMMYCLASS_LOCATION_PROP = "DummyClass"; 26 27 public static String DUMMYCLASS_LOCATION = System.getProperty(DUMMYCLASS_LOCATION_PROP); 28 29 static { 30 if (DUMMYCLASS_LOCATION == null) { 31 DUMMYCLASS_LOCATION = System.getProperty("ASPECTWERKZ_HOME") 32 + File.separator 33 + "target" 34 + File.separator 35 + "test-classes"; 36 } 37 } 38 39 /*** 40 * log 41 */ 42 private static void log(String s) { 43 System.out.println(s); 44 } 45 46 /*** 47 * launch all thread and join() with them 48 */ 49 public static void main(String[] args) throws Exception { 50 int thread = 2; 51 int count = 5; 52 int mspause = 5; 53 try { 54 thread = Integer.parseInt(args[0]); 55 count = Integer.parseInt(args[1]); 56 mspause = Integer.parseInt(args[2]); 57 } catch (Exception e) { 58 ; 59 } 60 long start = System.currentTimeMillis(); 61 log("BEGIN:" + thread + ':' + count + ':' + mspause + ':' + DUMMYCLASS_LOCATION); 62 Thread[] threads = new Thread[thread]; 63 for (int i = 0; i < thread; i++) { 64 Worker w = new Worker(count, mspause); 65 w.setPriority(Thread.MAX_PRIORITY - 1); 66 w.start(); 67 log("started " + i); 68 threads[i] = w; 69 } 70 for (int i = 0; i < thread; i++) { 71 threads[i].join(); 72 log("joined " + i); 73 } 74 log("END"); 75 log("( " + ((int) (System.currentTimeMillis() - start) / 1000) + " s)"); 76 log("classes=" + (thread * count * 2)); 77 System.exit(0); 78 } 79 80 private static class Worker extends Thread { 81 public static transient int total = 0; 82 83 int count = 10; 84 85 long mspause = 1000; 86 87 URL url = null; 88 89 public Worker(int count, long mspause) { 90 this.count = count; 91 this.mspause = mspause; 92 try { 93 this.url = new java.io.File(DUMMYCLASS_LOCATION).toURL(); 94 } catch (Exception e) { 95 e.printStackTrace(); 96 } 97 } 98 99 public void run() { 100 int i = 0; 101 while (i < count) { 102 try { 103 i++; 104 ClassLoader tmpLoader = new URLClassLoader(new URL[] { 105 url 106 }, null); 107 Class dummyClass = tmpLoader.loadClass("test.clapp.DummyClass"); 108 Object dummyInstance = dummyClass.newInstance(); 109 total++; 110 log(total 111 + " " 112 + this.getName() 113 + ':' 114 + i 115 + ":DumyClass.hashcode=" 116 + dummyInstance.getClass().hashCode()); 117 synchronized (this) { 118 wait(mspause); 119 } 120 } catch (Exception e) { 121 e.printStackTrace(); 122 } 123 } 124 } 125 } 126 }