View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.http.spi;
20  
21  import java.util.concurrent.Executor;
22  import java.util.concurrent.ExecutorService;
23  import java.util.concurrent.ThreadPoolExecutor;
24  import java.util.concurrent.TimeUnit;
25  
26  import org.eclipse.jetty.util.component.ContainerLifeCycle;
27  import org.eclipse.jetty.util.component.LifeCycle;
28  import org.eclipse.jetty.util.log.Log;
29  import org.eclipse.jetty.util.log.Logger;
30  import org.eclipse.jetty.util.thread.ThreadPool;
31  
32  public class DelegatingThreadPool extends ContainerLifeCycle implements ThreadPool
33  {
34      private static final Logger LOG = Log.getLogger(DelegatingThreadPool.class);
35      
36      private Executor _executor; // memory barrier provided by start/stop semantics
37  
38      public DelegatingThreadPool(Executor executor)
39      {
40          _executor=executor;
41          addBean(_executor);
42      }
43  
44      /* ------------------------------------------------------------ */
45      public Executor getExecutor()
46      {
47          return _executor;
48      }
49      
50      /* ------------------------------------------------------------ */
51      public void setExecutor(Executor executor)
52      {
53          if (isRunning())
54              throw new IllegalStateException(getState());
55          updateBean(_executor,executor);
56          _executor=executor;
57      }
58      
59      /* ------------------------------------------------------------ */
60      @Override
61      public void execute(Runnable job)
62      {
63          _executor.execute(job);
64      }
65  
66      /* ------------------------------------------------------------ */
67      @Override
68      public int getIdleThreads()
69      {
70          final Executor executor=_executor;
71          if (executor instanceof ThreadPool)
72              return ((ThreadPool)executor).getIdleThreads();
73          
74          if (executor instanceof ThreadPoolExecutor)
75          {
76              final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
77              return tpe.getPoolSize() - tpe.getActiveCount();
78          }
79          return -1;
80      }
81  
82      /* ------------------------------------------------------------ */
83      @Override
84      public int getThreads()
85      {
86          final Executor executor=_executor;
87          if (executor instanceof ThreadPool)
88              return ((ThreadPool)executor).getThreads();
89          
90          if (executor instanceof ThreadPoolExecutor)
91          {
92              final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
93              return tpe.getPoolSize();
94          }
95          return -1;
96      }
97  
98      /* ------------------------------------------------------------ */
99      @Override
100     public boolean isLowOnThreads()
101     {
102         final Executor executor=_executor;
103         if (executor instanceof ThreadPool)
104             return ((ThreadPool)executor).isLowOnThreads();
105         
106         if (executor instanceof ThreadPoolExecutor)
107         {
108             final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
109             // getActiveCount() locks the thread pool, so execute it last
110             return tpe.getPoolSize() == tpe.getMaximumPoolSize() &&
111                     tpe.getQueue().size() >= tpe.getPoolSize() - tpe.getActiveCount();
112         }
113         return false;
114     }
115 
116     /* ------------------------------------------------------------ */
117     @Override
118     public void join() throws InterruptedException
119     {
120         final Executor executor=_executor;
121         if (executor instanceof ThreadPool)
122             ((ThreadPool)executor).join();
123         else if (executor instanceof ExecutorService)
124             ((ExecutorService)executor).awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
125         else
126             throw new IllegalStateException();
127     }
128 
129     /* ------------------------------------------------------------ */
130     @Override
131     protected void doStop() throws Exception
132     {
133         super.doStop();
134         if (!(_executor instanceof LifeCycle) && (_executor instanceof ExecutorService))
135             ((ExecutorService)_executor).shutdownNow();
136     }
137 
138 }