2N/A/*
2N/A * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
2N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
2N/A *
2N/A * This code is free software; you can redistribute it and/or modify it
2N/A * under the terms of the GNU General Public License version 2 only, as
2N/A * published by the Free Software Foundation. Oracle designates this
2N/A * particular file as subject to the "Classpath" exception as provided
2N/A * by Oracle in the LICENSE file that accompanied this code.
2N/A *
2N/A * This code is distributed in the hope that it will be useful, but WITHOUT
2N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
2N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2N/A * version 2 for more details (a copy is included in the LICENSE file that
2N/A * accompanied this code).
2N/A *
2N/A * You should have received a copy of the GNU General Public License version
2N/A * 2 along with this work; if not, write to the Free Software Foundation,
2N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2N/A *
2N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2N/A * or visit www.oracle.com if you need additional information or have any
2N/A * questions.
2N/A */
2N/A
2N/Apackage sun.nio.ch;
2N/A
2N/Aimport java.util.concurrent.*;
2N/Aimport java.security.AccessController;
2N/Aimport sun.security.action.GetPropertyAction;
2N/Aimport sun.security.action.GetIntegerAction;
2N/A
2N/A/**
2N/A * Encapsulates a thread pool associated with a channel group.
2N/A */
2N/A
2N/Apublic class ThreadPool {
2N/A private static final String DEFAULT_THREAD_POOL_THREAD_FACTORY =
2N/A "java.nio.channels.DefaultThreadPool.threadFactory";
2N/A private static final String DEFAULT_THREAD_POOL_INITIAL_SIZE =
2N/A "java.nio.channels.DefaultThreadPool.initialSize";
2N/A private static final ThreadFactory defaultThreadFactory = new ThreadFactory() {
2N/A @Override
2N/A public Thread newThread(Runnable r) {
2N/A Thread t = new Thread(r);
2N/A t.setDaemon(true);
2N/A return t;
2N/A }
2N/A };
2N/A
2N/A private final ExecutorService executor;
2N/A
2N/A // indicates if thread pool is fixed size
2N/A private final boolean isFixed;
2N/A
2N/A // indicates the pool size (for a fixed thread pool configuratin this is
2N/A // the maximum pool size; for other thread pools it is the initial size)
2N/A private final int poolSize;
2N/A
2N/A private ThreadPool(ExecutorService executor,
2N/A boolean isFixed,
2N/A int poolSize)
2N/A {
2N/A this.executor = executor;
2N/A this.isFixed = isFixed;
2N/A this.poolSize = poolSize;
}
ExecutorService executor() {
return executor;
}
boolean isFixedThreadPool() {
return isFixed;
}
int poolSize() {
return poolSize;
}
static ThreadFactory defaultThreadFactory() {
return defaultThreadFactory;
}
private static class DefaultThreadPoolHolder {
final static ThreadPool defaultThreadPool = createDefault();
}
// return the default (system-wide) thread pool
static ThreadPool getDefault() {
return DefaultThreadPoolHolder.defaultThreadPool;
}
// create thread using default settings (configured by system properties)
static ThreadPool createDefault() {
// default the number of fixed threads to the hardware core count
int initialSize = getDefaultThreadPoolInitialSize();
if (initialSize < 0)
initialSize = Runtime.getRuntime().availableProcessors();
// default to thread factory that creates daemon threads
ThreadFactory threadFactory = getDefaultThreadPoolThreadFactory();
if (threadFactory == null)
threadFactory = defaultThreadFactory;
// create thread pool
ExecutorService executor =
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
Long.MAX_VALUE, TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
return new ThreadPool(executor, false, initialSize);
}
// create using given parameters
static ThreadPool create(int nThreads, ThreadFactory factory) {
if (nThreads <= 0)
throw new IllegalArgumentException("'nThreads' must be > 0");
ExecutorService executor = Executors.newFixedThreadPool(nThreads, factory);
return new ThreadPool(executor, true, nThreads);
}
// wrap a user-supplied executor
public static ThreadPool wrap(ExecutorService executor, int initialSize) {
if (executor == null)
throw new NullPointerException("'executor' is null");
// attempt to check if cached thread pool
if (executor instanceof ThreadPoolExecutor) {
int max = ((ThreadPoolExecutor)executor).getMaximumPoolSize();
if (max == Integer.MAX_VALUE) {
if (initialSize < 0) {
initialSize = Runtime.getRuntime().availableProcessors();
} else {
// not a cached thread pool so ignore initial size
initialSize = 0;
}
}
} else {
// some other type of thread pool
if (initialSize < 0)
initialSize = 0;
}
return new ThreadPool(executor, false, initialSize);
}
private static int getDefaultThreadPoolInitialSize() {
String propValue = AccessController.doPrivileged(new
GetPropertyAction(DEFAULT_THREAD_POOL_INITIAL_SIZE));
if (propValue != null) {
try {
return Integer.parseInt(propValue);
} catch (NumberFormatException x) {
throw new Error("Value of property '" + DEFAULT_THREAD_POOL_INITIAL_SIZE +
"' is invalid: " + x);
}
}
return -1;
}
private static ThreadFactory getDefaultThreadPoolThreadFactory() {
String propValue = AccessController.doPrivileged(new
GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY));
if (propValue != null) {
try {
Class<?> c = Class
.forName(propValue, true, ClassLoader.getSystemClassLoader());
return ((ThreadFactory)c.newInstance());
} catch (ClassNotFoundException x) {
throw new Error(x);
} catch (InstantiationException x) {
throw new Error(x);
} catch (IllegalAccessException x) {
throw new Error(x);
}
}
return null;
}
}