View Javadoc

1   package org.sourceforge.mbeanmonitoring.report;
2   
3   /**
4    **      Author:
5    **              Laurent Le Grandois <Laurent.Le.Grandois@gmail.com>
6    **              Gilles Bardouillet  <Gilles.Bardouillet@gmail.com>
7    **
8    **  This program is free software; you can redistribute it and/or modify
9    ** it under the terms of the GNU General Public License as published by
10   **  the Free Software Foundation; either version 2 of the License, or
11   **  (at your option) any later version.
12   **
13   ** This program is distributed in the hope that it will be useful,
14   **  but WITHOUT ANY WARRANTY; without even the implied warranty of
15   **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   **  GNU General Public License for more details.
17   **
18   **  You should have received a copy of the GNU General Public License
19   ** along with this program; if not, write to the Free Software
20   **
21   */
22  
23  import java.util.LinkedList;
24  import java.util.Timer;
25  import java.util.TimerTask;
26  
27  public class TasksScheduler extends TimerTask {
28  	private PoolWorker[] threads;
29  	private final LinkedList<Runnable> tasksToExecuteNow;
30  	private final LinkedList<Runnable> availableTasks;
31  
32  	public TasksScheduler() {
33  		tasksToExecuteNow = new LinkedList<Runnable>();
34  		availableTasks = new LinkedList<Runnable>();
35  	}
36  
37  	public void addRunnableTasks(Runnable r) {
38  		availableTasks.addLast(r);
39  	}
40  
41  	public void startScheduledTasks(int intervalInSec) {
42  		int maxThreadsNeeded = availableTasks.size();
43  		threads = new PoolWorker[maxThreadsNeeded];
44  		for (int i = 0; i < maxThreadsNeeded; i++) {
45  			threads[i] = new PoolWorker();
46  			threads[i].setId(i);
47  			threads[i].start();
48  		}
49  		System.out.println("Scheduler: TasksPool=" + maxThreadsNeeded + " / Interval=" + intervalInSec + "s");
50  		System.out.println("Scheduler: Hope each task does not last more than " + (intervalInSec * maxThreadsNeeded)
51  				+ "s !");
52  		Timer timer = new Timer();
53  		timer.schedule((TimerTask) this, 0, intervalInSec * 1000);
54  	}
55  
56  	// Finds an available task and puts it in the list of tasks to start now.
57  	public void run() {
58  		Runnable r;
59  		synchronized (availableTasks) {
60  			// Find a task available to be run
61  
62  			if (availableTasks.isEmpty())
63  				System.out.println("NO TASKS TO RUN... INCREASE THE TASKS POOL SIZE !");
64  
65  			while (availableTasks.isEmpty()) {
66  				try {
67  					availableTasks.wait();
68  				} catch (InterruptedException ignored) {
69  				}
70  			}
71  			r = (Runnable) availableTasks.removeFirst();
72  		}
73  		executeTask(r);
74  	}
75  
76  	public void executeTask(Runnable r) {
77  		synchronized (tasksToExecuteNow) {
78  			tasksToExecuteNow.addLast(r);
79  			tasksToExecuteNow.notify();
80  		}
81  	}
82  
83  	//////////////////////////////////////////////////////////////////////////////
84  
85  	private class PoolWorker extends Thread {
86  		private int ID = 0;
87  
88  		public void setId(int _id) {
89  			this.ID = _id;
90  		}
91  
92  		public void run() {
93  			Runnable r;
94  
95  			while (true) {
96  				synchronized (tasksToExecuteNow) {
97  					while (tasksToExecuteNow.isEmpty()) {
98  						try {
99  							tasksToExecuteNow.wait();
100 						} catch (InterruptedException ignored) {
101 						}
102 					}
103 					r = (Runnable) tasksToExecuteNow.removeFirst();
104 				}
105 
106 				// If we don't catch RuntimeException,
107 				// the pool could leak threads
108 				try {
109 					System.out.println("Worker [" + this.ID + "]: Task launched");
110 					long dureeDebut = System.currentTimeMillis();
111 					r.run();
112 					long dureeFin = System.currentTimeMillis();
113 					long tempsPasse = dureeFin - dureeDebut;
114 					if (tempsPasse < 0) {
115 						tempsPasse = 0;
116 					}
117 					System.out.println("Worker [" + this.ID + "]: Task done in " + tempsPasse + " ms");
118 
119 					// Puts back this task to the list of tasks available for a
120 					// run...
121 					synchronized (availableTasks) {
122 						availableTasks.addLast(r);
123 						availableTasks.notify();
124 					}
125 				} catch (RuntimeException e) {
126 					e.printStackTrace();
127 					// You might want to log something here
128 				}
129 			}
130 		}
131 	}
132 }