]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/util/thread/ScheduledExecutorScheduler.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / util / thread / ScheduledExecutorScheduler.java
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.util.thread;
20
21 import java.io.IOException;
22 import java.util.Arrays;
23 import java.util.List;
24 import java.util.concurrent.ScheduledFuture;
25 import java.util.concurrent.ScheduledThreadPoolExecutor;
26 import java.util.concurrent.ThreadFactory;
27 import java.util.concurrent.TimeUnit;
28
29 import org.eclipse.jetty.util.component.AbstractLifeCycle;
30 import org.eclipse.jetty.util.component.ContainerLifeCycle;
31 import org.eclipse.jetty.util.component.Dumpable;
32
33 /**
34  * Implementation of {@link Scheduler} based on JDK's {@link ScheduledThreadPoolExecutor}.
35  * <p />
36  * While use of {@link ScheduledThreadPoolExecutor} creates futures that will not be used,
37  * it has the advantage of allowing to set a property to remove cancelled tasks from its
38  * queue even if the task did not fire, which provides a huge benefit in the performance
39  * of garbage collection in young generation.
40  */
41 public class ScheduledExecutorScheduler extends AbstractLifeCycle implements Scheduler, Dumpable
42 {
43     private final String name;
44     private final boolean daemon;
45     private final ClassLoader classloader;
46     private volatile ScheduledThreadPoolExecutor scheduler;
47     private volatile Thread thread;
48
49     public ScheduledExecutorScheduler()
50     {
51         this(null, false);
52     }  
53
54     public ScheduledExecutorScheduler(String name, boolean daemon)
55     {
56         this (name,daemon, Thread.currentThread().getContextClassLoader());
57     }
58     
59     public ScheduledExecutorScheduler(String name, boolean daemon, ClassLoader threadFactoryClassLoader)
60     {
61         this.name = name == null ? "Scheduler-" + hashCode() : name;
62         this.daemon = daemon;
63         this.classloader = threadFactoryClassLoader;
64     }
65
66     @Override
67     protected void doStart() throws Exception
68     {
69         scheduler = new ScheduledThreadPoolExecutor(1, new ThreadFactory()
70         {
71             @Override
72             public Thread newThread(Runnable r)
73             {
74                 Thread thread = ScheduledExecutorScheduler.this.thread = new Thread(r, name);
75                 thread.setDaemon(daemon);
76                 thread.setContextClassLoader(classloader);
77                 return thread;
78             }
79         });
80         scheduler.setRemoveOnCancelPolicy(true);
81         super.doStart();
82     }
83
84     @Override
85     protected void doStop() throws Exception
86     {
87         scheduler.shutdownNow();
88         super.doStop();
89         scheduler = null;
90     }
91
92     @Override
93     public Task schedule(Runnable task, long delay, TimeUnit unit)
94     {
95         ScheduledThreadPoolExecutor s = scheduler;
96         if (s==null)
97             return new Task(){
98                 @Override
99                 public boolean cancel()
100                 {
101                     return false;
102                 }};
103
104         ScheduledFuture<?> result = s.schedule(task, delay, unit);
105         return new ScheduledFutureTask(result);
106     }
107
108     @Override
109     public String dump()
110     {
111         return ContainerLifeCycle.dump(this);
112     }
113
114     @Override
115     public void dump(Appendable out, String indent) throws IOException
116     {
117         ContainerLifeCycle.dumpObject(out, this);
118         Thread thread = this.thread;
119         if (thread != null)
120         {
121             List<StackTraceElement> frames = Arrays.asList(thread.getStackTrace());
122             ContainerLifeCycle.dump(out, indent, frames);
123         }
124     }
125
126     private class ScheduledFutureTask implements Task
127     {
128         private final ScheduledFuture<?> scheduledFuture;
129
130         public ScheduledFutureTask(ScheduledFuture<?> scheduledFuture)
131         {
132             this.scheduledFuture = scheduledFuture;
133         }
134
135         @Override
136         public boolean cancel()
137         {
138             return scheduledFuture.cancel(false);
139         }
140     }
141 }