1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 import java.util.concurrent.atomic.AtomicInteger; 26 import java.util.List; 27 import java.util.HashMap; 28 import java.util.ArrayList; 29 30 public class ParallelLambdaLoad { 31 public static int NUM_THREADS = 10; 32 public static int MAX_CLASSES = 10; 33 public static AtomicInteger num_ready[]; 34 public static boolean isRuntime; 35 36 public static void main(String args[]) throws Throwable { 37 isRuntime = (args.length == 1 && args[0].equals("run")) ? true : false; 38 num_ready = new AtomicInteger[MAX_CLASSES]; 39 for (int i = 0; i < MAX_CLASSES; i++) { 40 num_ready[i] = new AtomicInteger(); 41 } 42 43 ArrayList<Thread> list = new ArrayList<>(); 44 45 list.add(new Thread(() -> { 46 DoSomething ds = new DoSomething(0); 47 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 48 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 49 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 50 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 51 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 52 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 53 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 54 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 55 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 56 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 57 })); 58 list.add(new Thread(() -> { 59 DoSomething ds = new DoSomething(1); 60 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 61 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 62 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 63 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 64 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 65 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 66 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 67 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 68 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 69 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 70 })); 71 list.add(new Thread(() -> { 72 DoSomething ds = new DoSomething(2); 73 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 74 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 75 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 76 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 77 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 78 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 79 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 80 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 81 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 82 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 83 })); 84 list.add(new Thread(() -> { 85 DoSomething ds = new DoSomething(3); 86 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 87 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 88 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 89 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 90 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 91 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 92 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 93 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 94 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 95 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 96 })); 97 list.add(new Thread(() -> { 98 DoSomething ds = new DoSomething(4); 99 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 100 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 101 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 102 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 103 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 104 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 105 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 106 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 107 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 108 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 109 })); 110 list.add(new Thread(() -> { 111 DoSomething ds = new DoSomething(5); 112 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 113 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 114 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 115 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 116 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 117 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 118 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 119 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 120 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 121 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 122 })); 123 list.add(new Thread(() -> { 124 DoSomething ds = new DoSomething(6); 125 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 126 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 127 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 128 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 129 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 130 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 131 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 132 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 133 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 134 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 135 })); 136 list.add(new Thread(() -> { 137 DoSomething ds = new DoSomething(7); 138 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 139 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 140 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 141 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 142 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 143 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 144 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 145 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 146 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 147 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 148 })); 149 list.add(new Thread(() -> { 150 DoSomething ds = new DoSomething(8); 151 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 152 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 153 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 154 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 155 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 156 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 157 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 158 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 159 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 160 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 161 })); 162 list.add(new Thread(() -> { 163 DoSomething ds = new DoSomething(9); 164 {ThreadUtil.WaitForLock(0); Runnable runner = ds::run; runner.run();} 165 {ThreadUtil.WaitForLock(1); Runnable runner = ds::run; runner.run();} 166 {ThreadUtil.WaitForLock(2); Runnable runner = ds::run; runner.run();} 167 {ThreadUtil.WaitForLock(3); Runnable runner = ds::run; runner.run();} 168 {ThreadUtil.WaitForLock(4); Runnable runner = ds::run; runner.run();} 169 {ThreadUtil.WaitForLock(5); Runnable runner = ds::run; runner.run();} 170 {ThreadUtil.WaitForLock(6); Runnable runner = ds::run; runner.run();} 171 {ThreadUtil.WaitForLock(7); Runnable runner = ds::run; runner.run();} 172 {ThreadUtil.WaitForLock(8); Runnable runner = ds::run; runner.run();} 173 {ThreadUtil.WaitForLock(9); Runnable runner = ds::run; runner.run();} 174 })); 175 176 177 for (Thread t : list) { 178 t.start(); 179 } 180 181 for (Thread t : list) { 182 t.join(); 183 } 184 185 synchronized(map) { 186 System.out.println("map size " + map.size()); 187 int expectedSize = NUM_THREADS * MAX_CLASSES; 188 if (map.size() != expectedSize) { 189 throw new RuntimeException("Expected number of lamdba classes is " + 190 expectedSize + " but got only " + map.size()); 191 } 192 } 193 } 194 195 static HashMap<Class<?>, Class<?>> map = new HashMap<>(); 196 } 197 198 class DoSomething { 199 DoSomething(int dummy) {} 200 201 public void run() { 202 Class<?> c = LambdaVerification.getCallerClass(1); 203 synchronized(ParallelLambdaLoad.map) { 204 ParallelLambdaLoad.map.put(c, c); 205 } 206 LambdaVerification.verifyCallerIsArchivedLambda(ParallelLambdaLoad.isRuntime); 207 } 208 } 209 210 class ThreadUtil { 211 static void WaitForLock(int i) { 212 // Spin until every thread is ready to proceed 213 ParallelLambdaLoad.num_ready[i].incrementAndGet(); 214 while (ParallelLambdaLoad.num_ready[i].intValue() < ParallelLambdaLoad.NUM_THREADS) { 215 ; 216 } 217 } 218 }