### Question:
SparkRunnerClassLoader extends URLClassLoader { @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { if (API_CLASSES.contains(name) || (!name.startsWith("io.cdap.cdap.api.spark.") && !name.startsWith("io.cdap.cdap.app.deploy.spark.") && !name.startsWith("io.cdap.cdap.app.runtime.spark.") && !name.startsWith("org.apache.spark.") && !name.startsWith("org.spark-project.") && !name.startsWith("akka.") && !name.startsWith("com.typesafe.") && !name.startsWith("com.esotericsoftware.") && !name.startsWith("com.twitter.chill.")) && !name.startsWith("org.codehaus.janino.") && !name.startsWith("com.fasterxml.jackson.") && !name.startsWith("com.codahale.metrics.") && !name.startsWith("py4j.") ) { return super.loadClass(name, resolve); } synchronized (getClassLoadingLock(name)) { Class<?> cls = findLoadedClass(name); if (cls != null) { return cls; } try (InputStream is = ClassLoaders.openResource(this, name.replace('.', '/') + ".class")) { if (is == null) { throw new ClassNotFoundException("Failed to find resource for class " + name); } byte[] byteCode = rewriter.rewriteClass(name, is); if (byteCode == null) { cls = findClass(name); } else { cls = defineClass(name, byteCode, 0, byteCode.length); } if (resolve) { resolveClass(cls); } return cls; } catch (IOException e) { throw new ClassNotFoundException("Failed to read class definition for class " + name, e); } } } SparkRunnerClassLoader(URL[] urls, @Nullable ClassLoader parent, boolean rewriteYarnClient); @Override InputStream getResourceAsStream(String name); @Override void close();  }### Answer:
@Test public void testConcurrentLoadClass() throws Exception { ExecutorService executor = Executors.newFixedThreadPool(2); try { for (int i = 0; i < 100; i++) { List<URL> urls = ClassLoaders.getClassLoaderURLs(getClass().getClassLoader(), new ArrayList<URL>()); final URL[] urlArray = urls.toArray(new URL[urls.size()]); SparkRunnerClassLoader classLoader = new SparkRunnerClassLoader(urlArray, getClass().getClassLoader(), false); CyclicBarrier barrier = new CyclicBarrier(2); String className = "org.apache.spark.SparkContext"; CompletionService<?> completionService = new ExecutorCompletionService<>(executor); for (int j = 0; j < 2; j++) { completionService.submit(() -> { barrier.await(); classLoader.loadClass(className); return null; }); } for (int j = 0; j < 2; j++) { completionService.take().get(); } } } finally { executor.shutdownNow(); } }