Path: blob/master/src/java.base/share/classes/sun/nio/ch/ThreadPool.java
41159 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.ch;2627import java.util.concurrent.*;28import java.security.AccessController;29import java.security.PrivilegedAction;30import sun.security.action.GetPropertyAction;31import sun.security.action.GetIntegerAction;32import jdk.internal.misc.InnocuousThread;3334/**35* Encapsulates a thread pool associated with a channel group.36*/3738public class ThreadPool {39private static final String DEFAULT_THREAD_POOL_THREAD_FACTORY =40"java.nio.channels.DefaultThreadPool.threadFactory";41private static final String DEFAULT_THREAD_POOL_INITIAL_SIZE =42"java.nio.channels.DefaultThreadPool.initialSize";4344private final ExecutorService executor;4546// indicates if thread pool is fixed size47private final boolean isFixed;4849// indicates the pool size (for a fixed thread pool configuratin this is50// the maximum pool size; for other thread pools it is the initial size)51private final int poolSize;5253private ThreadPool(ExecutorService executor,54boolean isFixed,55int poolSize)56{57this.executor = executor;58this.isFixed = isFixed;59this.poolSize = poolSize;60}6162ExecutorService executor() {63return executor;64}6566boolean isFixedThreadPool() {67return isFixed;68}6970int poolSize() {71return poolSize;72}7374@SuppressWarnings("removal")75static ThreadFactory defaultThreadFactory() {76if (System.getSecurityManager() == null) {77return (Runnable r) -> {78Thread t = new Thread(r);79t.setDaemon(true);80return t;81};82} else {83return (Runnable r) -> {84PrivilegedAction<Thread> action = () -> {85Thread t = InnocuousThread.newThread(r);86t.setDaemon(true);87return t;88};89return AccessController.doPrivileged(action);90};91}92}9394private static class DefaultThreadPoolHolder {95static final ThreadPool defaultThreadPool = createDefault();96}9798// return the default (system-wide) thread pool99static ThreadPool getDefault() {100return DefaultThreadPoolHolder.defaultThreadPool;101}102103// create thread using default settings (configured by system properties)104static ThreadPool createDefault() {105// default the number of fixed threads to the hardware core count106int initialSize = getDefaultThreadPoolInitialSize();107if (initialSize < 0)108initialSize = Runtime.getRuntime().availableProcessors();109// default to thread factory that creates daemon threads110ThreadFactory threadFactory = getDefaultThreadPoolThreadFactory();111if (threadFactory == null)112threadFactory = defaultThreadFactory();113// create thread pool114ExecutorService executor = Executors.newCachedThreadPool(threadFactory);115return new ThreadPool(executor, false, initialSize);116}117118// create using given parameters119static ThreadPool create(int nThreads, ThreadFactory factory) {120if (nThreads <= 0)121throw new IllegalArgumentException("'nThreads' must be > 0");122ExecutorService executor = Executors.newFixedThreadPool(nThreads, factory);123return new ThreadPool(executor, true, nThreads);124}125126// wrap a user-supplied executor127public static ThreadPool wrap(ExecutorService executor, int initialSize) {128if (executor == null)129throw new NullPointerException("'executor' is null");130// attempt to check if cached thread pool131if (executor instanceof ThreadPoolExecutor) {132int max = ((ThreadPoolExecutor)executor).getMaximumPoolSize();133if (max == Integer.MAX_VALUE) {134if (initialSize < 0) {135initialSize = Runtime.getRuntime().availableProcessors();136} else {137// not a cached thread pool so ignore initial size138initialSize = 0;139}140}141} else {142// some other type of thread pool143if (initialSize < 0)144initialSize = 0;145}146return new ThreadPool(executor, false, initialSize);147}148149private static int getDefaultThreadPoolInitialSize() {150@SuppressWarnings("removal")151String propValue = AccessController.doPrivileged(new152GetPropertyAction(DEFAULT_THREAD_POOL_INITIAL_SIZE));153if (propValue != null) {154try {155return Integer.parseInt(propValue);156} catch (NumberFormatException x) {157throw new Error("Value of property '" + DEFAULT_THREAD_POOL_INITIAL_SIZE +158"' is invalid: " + x);159}160}161return -1;162}163164private static ThreadFactory getDefaultThreadPoolThreadFactory() {165@SuppressWarnings("removal")166String propValue = AccessController.doPrivileged(new167GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY));168if (propValue != null) {169try {170@SuppressWarnings("deprecation")171Object tmp = Class172.forName(propValue, true, ClassLoader.getSystemClassLoader()).newInstance();173return (ThreadFactory)tmp;174} catch (ClassNotFoundException | InstantiationException | IllegalAccessException x) {175throw new Error(x);176}177}178return null;179}180}181182183