]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.thread/src/org/simantics/utils/threads/Throttler.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils.thread / src / org / simantics / utils / threads / Throttler.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.utils.threads;\r
13 \r
14 import java.util.concurrent.TimeUnit;\r
15 \r
16 /**\r
17  * @author Antti Villberg\r
18  */\r
19 public class Throttler implements Runnable {\r
20 \r
21         final private IThreadWorkQueue thread;\r
22         final private int interval;\r
23 \r
24         private boolean isScheduling = false;\r
25 \r
26         private long[] dispatchTimes;\r
27         private long lastQueueTime;\r
28 \r
29         private int dispatchTimePointer = 0;\r
30 \r
31         private Runnable todo;\r
32 \r
33         public Throttler(IThreadWorkQueue thread, int interval, int queueLength) {\r
34 \r
35                 this.thread = thread;\r
36                 this.interval = interval;\r
37 \r
38                 long currentTime = System.currentTimeMillis();\r
39 \r
40                 dispatchTimes = new long[queueLength];\r
41                 for(int i=0;i<dispatchTimes.length;i++)\r
42                         dispatchTimes[i] = currentTime - interval;\r
43 \r
44                 lastQueueTime = Long.MAX_VALUE;\r
45 \r
46         }\r
47 \r
48         public synchronized void run() {\r
49 \r
50                 if(todo != null) {\r
51                         thread.asyncExec(todo);\r
52                         todo = null;\r
53                         ThreadUtils.getTimer().schedule(this, interval, TimeUnit.MILLISECONDS);\r
54                 } else {\r
55                         isScheduling = false;\r
56                 }\r
57 \r
58         }\r
59         \r
60         public synchronized void schedule(Runnable r) {\r
61 \r
62                 assert(thread.currentThreadAccess());\r
63                 \r
64                 dispatch(r);\r
65 \r
66                 if(getQueueTime() < interval) {\r
67 \r
68                         isScheduling = true;\r
69                         ThreadUtils.getTimer().schedule(this, interval, TimeUnit.MILLISECONDS);\r
70 \r
71                 }\r
72 \r
73         }\r
74 \r
75         private long getQueueTime() {\r
76                 return lastQueueTime;\r
77         }\r
78 \r
79         private void dispatch(Runnable runnable) {\r
80 \r
81                 long time = System.currentTimeMillis();\r
82                 lastQueueTime = time - dispatchTimes[dispatchTimePointer];\r
83                 dispatchTimes[dispatchTimePointer] = time;\r
84                 dispatchTimePointer = ((dispatchTimePointer+1) % dispatchTimes.length);\r
85 \r
86                 if(!isScheduling) {\r
87                         todo = null;\r
88                         runnable.run();\r
89                 } else {\r
90                         todo = runnable;\r
91                 }\r
92 \r
93         }\r
94 \r
95 }\r