jdk/src/share/classes/sun/nio/ch/ThreadPool.java
changeset 2057 3acf8e5e2ca0
child 5506 202f599c92aa
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
       
     1 /*
       
     2  * Copyright 2008-2009 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.nio.ch;
       
    27 
       
    28 import java.util.concurrent.*;
       
    29 import java.security.AccessController;
       
    30 import sun.security.action.GetPropertyAction;
       
    31 import sun.security.action.GetIntegerAction;
       
    32 
       
    33 /**
       
    34  * Encapsulates a thread pool associated with a channel group.
       
    35  */
       
    36 
       
    37 public class ThreadPool {
       
    38     private static final String DEFAULT_THREAD_POOL_THREAD_FACTORY =
       
    39         "java.nio.channels.DefaultThreadPool.threadFactory";
       
    40     private static final String DEFAULT_THREAD_POOL_INITIAL_SIZE =
       
    41         "java.nio.channels.DefaultThreadPool.initialSize";
       
    42     private static final ThreadFactory defaultThreadFactory = new ThreadFactory() {
       
    43          @Override
       
    44          public Thread newThread(Runnable r) {
       
    45              Thread t = new Thread(r);
       
    46              t.setDaemon(true);
       
    47              return t;
       
    48         }
       
    49      };
       
    50 
       
    51     private final ExecutorService executor;
       
    52 
       
    53     // indicates if thread pool is fixed size
       
    54     private final boolean isFixed;
       
    55 
       
    56     // indicates the pool size (for a fixed thread pool configuratin this is
       
    57     // the maximum pool size; for other thread pools it is the initial size)
       
    58     private final int poolSize;
       
    59 
       
    60     private ThreadPool(ExecutorService executor,
       
    61                        boolean isFixed,
       
    62                        int poolSize)
       
    63     {
       
    64         this.executor = executor;
       
    65         this.isFixed = isFixed;
       
    66         this.poolSize = poolSize;
       
    67     }
       
    68 
       
    69     ExecutorService executor() {
       
    70         return executor;
       
    71     }
       
    72 
       
    73     boolean isFixedThreadPool() {
       
    74         return isFixed;
       
    75     }
       
    76 
       
    77     int poolSize() {
       
    78         return poolSize;
       
    79     }
       
    80 
       
    81     static ThreadFactory defaultThreadFactory() {
       
    82         return defaultThreadFactory;
       
    83     }
       
    84 
       
    85     private static class DefaultThreadPoolHolder {
       
    86         final static ThreadPool defaultThreadPool = createDefault();
       
    87     }
       
    88 
       
    89     // return the default (system-wide) thread pool
       
    90     static ThreadPool getDefault() {
       
    91         return DefaultThreadPoolHolder.defaultThreadPool;
       
    92     }
       
    93 
       
    94     // create thread using default settings (configured by system properties)
       
    95     static ThreadPool createDefault() {
       
    96         // default the number of fixed threads to the hardware core count
       
    97         int initialSize = getDefaultThreadPoolInitialSize();
       
    98         if (initialSize < 0)
       
    99             initialSize = Runtime.getRuntime().availableProcessors();
       
   100         // default to thread factory that creates daemon threads
       
   101         ThreadFactory threadFactory = getDefaultThreadPoolThreadFactory();
       
   102         if (threadFactory == null)
       
   103             threadFactory = defaultThreadFactory;
       
   104         // create thread pool
       
   105         ExecutorService executor =
       
   106             new ThreadPoolExecutor(0, Integer.MAX_VALUE,
       
   107                                    Long.MAX_VALUE, TimeUnit.MILLISECONDS,
       
   108                                    new SynchronousQueue<Runnable>(),
       
   109                                    threadFactory);
       
   110         return new ThreadPool(executor, false, initialSize);
       
   111     }
       
   112 
       
   113     // create using given parameters
       
   114     static ThreadPool create(int nThreads, ThreadFactory factory) {
       
   115         if (nThreads <= 0)
       
   116             throw new IllegalArgumentException("'nThreads' must be > 0");
       
   117         ExecutorService executor = Executors.newFixedThreadPool(nThreads, factory);
       
   118         return new ThreadPool(executor, true, nThreads);
       
   119     }
       
   120 
       
   121     // wrap a user-supplied executor
       
   122     public static ThreadPool wrap(ExecutorService executor, int initialSize) {
       
   123         if (executor == null)
       
   124             throw new NullPointerException("'executor' is null");
       
   125         // attempt to check if cached thread pool
       
   126         if (executor instanceof ThreadPoolExecutor) {
       
   127             int max = ((ThreadPoolExecutor)executor).getMaximumPoolSize();
       
   128             if (max == Integer.MAX_VALUE) {
       
   129                 if (initialSize < 0) {
       
   130                     initialSize = Runtime.getRuntime().availableProcessors();
       
   131                 } else {
       
   132                    // not a cached thread pool so ignore initial size
       
   133                     initialSize = 0;
       
   134                 }
       
   135             }
       
   136         } else {
       
   137             // some other type of thread pool
       
   138             if (initialSize < 0)
       
   139                 initialSize = 0;
       
   140         }
       
   141         return new ThreadPool(executor, false, initialSize);
       
   142     }
       
   143 
       
   144     private static int getDefaultThreadPoolInitialSize() {
       
   145         String propValue = AccessController.doPrivileged(new
       
   146             GetPropertyAction(DEFAULT_THREAD_POOL_INITIAL_SIZE));
       
   147         if (propValue != null) {
       
   148             try {
       
   149                 return Integer.parseInt(propValue);
       
   150             } catch (NumberFormatException x) {
       
   151                 throw new Error("Value of property '" + DEFAULT_THREAD_POOL_INITIAL_SIZE +
       
   152                     "' is invalid: " + x);
       
   153             }
       
   154         }
       
   155         return -1;
       
   156     }
       
   157 
       
   158     private static ThreadFactory getDefaultThreadPoolThreadFactory() {
       
   159         String propValue = AccessController.doPrivileged(new
       
   160             GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY));
       
   161         if (propValue != null) {
       
   162             try {
       
   163                 Class<?> c = Class
       
   164                     .forName(propValue, true, ClassLoader.getSystemClassLoader());
       
   165                 return ((ThreadFactory)c.newInstance());
       
   166             } catch (ClassNotFoundException x) {
       
   167                 throw new Error(x);
       
   168             } catch (InstantiationException x) {
       
   169                 throw new Error(x);
       
   170             } catch (IllegalAccessException x) {
       
   171                 throw new Error(x);
       
   172             }
       
   173         }
       
   174         return null;
       
   175     }
       
   176 }