View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.RejectedExecutionException;
24  import java.util.concurrent.ThreadPoolExecutor;
25  import java.util.concurrent.TimeUnit;
26  
27  import org.eclipse.jetty.util.component.ContainerLifeCycle;
28  import org.eclipse.jetty.util.component.LifeCycle;
29  import org.eclipse.jetty.util.log.Log;
30  import org.eclipse.jetty.util.log.Logger;
31  import org.eclipse.jetty.util.thread.ThreadPool;
32  
33  public class DelegatingThreadPool extends ContainerLifeCycle implements ThreadPool
34  {
35      private static final Logger LOG = Log.getLogger(DelegatingThreadPool.class);
36      
37      private Executor _executor; // memory barrier provided by start/stop semantics
38  
39      public DelegatingThreadPool(Executor executor)
40      {
41          _executor=executor;
42          addBean(_executor);
43      }
44  
45      /* ------------------------------------------------------------ */
46      public Executor getExecutor()
47      {
48          return _executor;
49      }
50      
51      /* ------------------------------------------------------------ */
52      public void setExecutor(Executor executor)
53      {
54          if (isRunning())
55              throw new IllegalStateException(getState());
56          updateBean(_executor,executor);
57          _executor=executor;
58      }
59      
60      /* ------------------------------------------------------------ */
61      @Override
62      public void execute(Runnable job)
63      {
64          _executor.execute(job);
65      }
66  
67  
68      /* ------------------------------------------------------------ */
69      @Override
70      public boolean dispatch(Runnable job)
71      {
72          final Executor executor=_executor;
73          if (executor instanceof ThreadPool)
74              return ((ThreadPool)executor).dispatch(job);
75  
76          try
77          {
78              _executor.execute(job);
79              return true;
80          }
81          catch(RejectedExecutionException e)
82          {
83              LOG.warn(e);
84              return false;
85          }
86      }
87  
88      /* ------------------------------------------------------------ */
89      @Override
90      public int getIdleThreads()
91      {
92          final Executor executor=_executor;
93          if (executor instanceof ThreadPool)
94              return ((ThreadPool)executor).getIdleThreads();
95          
96          if (executor instanceof ThreadPoolExecutor)
97          {
98              final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
99              return tpe.getPoolSize() - tpe.getActiveCount();
100         }
101         return -1;
102     }
103 
104     /* ------------------------------------------------------------ */
105     @Override
106     public int getThreads()
107     {
108         final Executor executor=_executor;
109         if (executor instanceof ThreadPool)
110             return ((ThreadPool)executor).getThreads();
111         
112         if (executor instanceof ThreadPoolExecutor)
113         {
114             final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
115             return tpe.getPoolSize();
116         }
117         return -1;
118     }
119 
120     /* ------------------------------------------------------------ */
121     @Override
122     public boolean isLowOnThreads()
123     {
124         final Executor executor=_executor;
125         if (executor instanceof ThreadPool)
126             return ((ThreadPool)executor).isLowOnThreads();
127         
128         if (executor instanceof ThreadPoolExecutor)
129         {
130             final ThreadPoolExecutor tpe = (ThreadPoolExecutor)executor;
131             // getActiveCount() locks the thread pool, so execute it last
132             return tpe.getPoolSize() == tpe.getMaximumPoolSize() &&
133                     tpe.getQueue().size() >= tpe.getPoolSize() - tpe.getActiveCount();
134         }
135         return false;
136     }
137 
138     /* ------------------------------------------------------------ */
139     @Override
140     public void join() throws InterruptedException
141     {
142         final Executor executor=_executor;
143         if (executor instanceof ThreadPool)
144             ((ThreadPool)executor).join();
145         else if (executor instanceof ExecutorService)
146             ((ExecutorService)executor).awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
147         else
148             throw new IllegalStateException();
149     }
150 
151     /* ------------------------------------------------------------ */
152     @Override
153     protected void doStop() throws Exception
154     {
155         super.doStop();
156         if (!(_executor instanceof LifeCycle) && (_executor instanceof ExecutorService))
157             ((ExecutorService)_executor).shutdownNow();
158     }
159 
160 }