diff --git a/src/org/hwo/tasklet/Tasklet.java b/src/org/hwo/tasklet/Tasklet.java index a493e40..38bbe10 100644 --- a/src/org/hwo/tasklet/Tasklet.java +++ b/src/org/hwo/tasklet/Tasklet.java @@ -1,7 +1,42 @@ package org.hwo.tasklet; -public interface Tasklet { - public void run(Object arg); +public abstract class Tasklet { + + private String description; + private boolean started; + private String progress; + + public Tasklet(String description){ + this.description = description; + } + public Tasklet(){ + this.description = "anonymous"; + } + + public String getDescription() { + return description; + } + + public boolean isStarted() { + return started; + } + public void setStarted(boolean started) { + this.started = started; + } + + public String getProgress() { + return progress; + } + public void setProgress(String progress) { + this.progress = progress; + } + + public abstract void run(); + + @Override + public String toString() { + return String.format("%s %s %s",description,isStarted() ? "läuft" : "wartet", (this.progress==null) ? "" : String.format("[%s]", this.progress)); + } } diff --git a/src/org/hwo/tasklet/TaskletListener.java b/src/org/hwo/tasklet/TaskletListener.java new file mode 100644 index 0000000..a35762c --- /dev/null +++ b/src/org/hwo/tasklet/TaskletListener.java @@ -0,0 +1,9 @@ +package org.hwo.tasklet; + +public interface TaskletListener { + + void taskletQueued(TaskletManager manager,Tasklet tasklet); + void taskletStarted(TaskletManager manager,Tasklet tasklet); + void taskletFinished(TaskletManager manager,Tasklet tasklet); + void taskletProgressChanged(TaskletManager manager,Tasklet tasklet); +} diff --git a/src/org/hwo/tasklet/TaskletManager.java b/src/org/hwo/tasklet/TaskletManager.java new file mode 100644 index 0000000..069905c --- /dev/null +++ b/src/org/hwo/tasklet/TaskletManager.java @@ -0,0 +1,128 @@ +package org.hwo.tasklet; + +import java.util.LinkedList; +import java.util.List; + +public class TaskletManager { + + private static TaskletManager _TaskletManager = new TaskletManager(); + public static TaskletManager instance(){ + return _TaskletManager; + } + + List taskletListeners; + List taskletThreads; + + List tasklets; + + int threads; + boolean shuttingDown; + + public TaskletManager(){ + taskletListeners = new LinkedList(); + taskletThreads = new LinkedList(); + tasklets = new LinkedList(); + threads = 1; + } + + public synchronized void addTaskletListener(TaskletListener listener){ + taskletListeners.add(listener); + } + public synchronized void removeTaskletListener(TaskletListener listener){ + taskletListeners.remove(listener); + } + + public synchronized int getThreads() { + return threads; + } + public synchronized void setThreads(int threads) { + this.threads = threads; + } + + public synchronized void fireTaskletQueued(Tasklet tasklet){ + for (TaskletListener l:taskletListeners) + l.taskletQueued(this, tasklet); + } + public synchronized void fireTaskletStarted(Tasklet tasklet){ + for (TaskletListener l:taskletListeners) + l.taskletStarted(this, tasklet); + } + public synchronized void fireTaskletFinished(Tasklet tasklet){ + for (TaskletListener l:taskletListeners) + l.taskletFinished(this, tasklet); + } + public synchronized void fireTaskletProgressChanged(Tasklet tasklet){ + for (TaskletListener l:taskletListeners) + l.taskletProgressChanged(this, tasklet); + } + + public synchronized void enqueue(Tasklet tasklet){ + if (taskletThreads.size() < threads){ + taskletThreads.add(new TaskletThread(this)); + } + + tasklets.add(tasklet); + fireTaskletQueued(tasklet); + + this.notify(); + } + + public synchronized Tasklet pop(){ + if (tasklets.size()>0) + return tasklets.remove(0); + return null; + } + + public int getThreadPoolSize(){ + return taskletThreads.size(); + } + + public void shutdown(){ + synchronized (this) { + shuttingDown = true; + setThreads(0); + } + + while (taskletThreads.size() > 0){ + try { + Thread.sleep(50); + synchronized (this) { + this.notifyAll(); + } + + } catch (InterruptedException ex){ + ex.printStackTrace(); + } + } + } + + public boolean isShuttingDown() { + return shuttingDown; + } + + public synchronized void removeTaskletThread(TaskletThread taskletThread){ + taskletThreads.remove(taskletThread); + } + + private Tasklet findTasklet(){ + for (TaskletThread thread: this.taskletThreads){ + if (Thread.currentThread().equals(thread)){ + return thread.getCurrentTasklet(); + } + } + return null; + } + + public synchronized void setProgress(double percentage){ + setProgress(String.format("%d%%", new Double(percentage * 100).intValue())); + } + + public synchronized void setProgress(String progress){ + Tasklet c = findTasklet(); + if (c != null){ + c.setProgress(progress); + fireTaskletProgressChanged(c); + } + } + +} diff --git a/src/org/hwo/tasklet/TaskletThread.java b/src/org/hwo/tasklet/TaskletThread.java index 2861c63..5cb0ded 100644 --- a/src/org/hwo/tasklet/TaskletThread.java +++ b/src/org/hwo/tasklet/TaskletThread.java @@ -7,62 +7,65 @@ import java.util.Stack; import org.hwo.fifo.FiFo; public class TaskletThread extends Thread { - - private class QueuedTasklet - { - private Tasklet tasklet; - private Object argument; + TaskletManager manager; + Tasklet currentTasklet; + + public TaskletThread(TaskletManager manager) { + this.manager = manager; + this.currentTasklet = null; - public QueuedTasklet(Tasklet tasklet,Object argument) - { - this.tasklet = tasklet; - this.argument = argument; - } - } - - private FiFo queuedTasklets = new FiFo(); - - public TaskletThread() { start(); } - public void queue(Tasklet tasklet,Object arg) - { - synchronized (queuedTasklets) { - queuedTasklets.push(new QueuedTasklet(tasklet,arg)); - } - queuedTasklets.notify(); + public Tasklet getCurrentTasklet() { + return currentTasklet; + } + + private void removeFromManager(){ + manager.removeTaskletThread(this); } @Override public void run() { while (true) { - QueuedTasklet queuedTasklet = null; + Tasklet tasklet = manager.pop(); - synchronized (queuedTasklets) { + while (tasklet != null){ + tasklet.setStarted(true); + manager.fireTaskletStarted(tasklet); + currentTasklet = tasklet; try { - queuedTasklets.wait(100); - queuedTasklet = queuedTasklets.pull(); - } catch (InterruptedException e) { + tasklet.run(); + } catch (Exception e){ + System.err.println("Tasklet threw Exception:"); e.printStackTrace(); } + + currentTasklet = null; + tasklet.setStarted(false); + manager.fireTaskletFinished(tasklet); + + tasklet = manager.pop(); } - if (queuedTasklet != null) - { - try - { - queuedTasklet.tasklet.run(queuedTasklet.argument); - } catch (Exception ex) - { - System.err.println("Tasklet throwed Exception: " + ex.toString()); + synchronized (manager) { + try { + if (manager.getThreadPoolSize() > manager.getThreads()){ + removeFromManager(); + return; + } + + manager.wait(); + } catch (InterruptedException ex){ ex.printStackTrace(); } } - if (isInterrupted()) + if (manager.isShuttingDown()){ + removeFromManager(); return; + } } }