I have this thread class I am trying to work with.
public class Execution implements Runnable {
public String name;
public double time;
public double timeToDisplay;
public Execution(String name, double et){
this.name = name;
this.time = (et*1000);
}
public void run(){
try{
}catch(Exception e){}
}
/**
* #return the timeToDisplay
*/
public double getTimeToDisplay() {
return timeToDisplay;
}
/**
* #param timeToDisplay the timeToDisplay to set
*/
public void setTimeToDisplay(double timeToDisplay) {
this.timeToDisplay = timeToDisplay;
}
}
I am trying to get the variable timeToDisplay to change every milisecond that the thread runs. The thread is supposed to run for a set amount of et(execution time).
All I need the task to do is run according to the execution time and assign the current time to timeToDisplay Variable.
Here is a sample of a simple scheduled job with comments. Feel free to ask for details.
public class Execution implements Runnable {
public String name;
protected long startedAtMs;
// total timeout in ms
protected long timeoutMs;
// rate: 1 execution per 2 ms
private long rateMs = 2;
// when was the previousExecution
private long prevExecutionMs;
// action to run each 1 ms
protected Runnable action;
public Execution(String name, double et, Runnable action) {
this.name = name;
this.action = action;
this.timeoutMs = (long) (et * 1000);
}
public void run() {
startedAtMs = System.currentTimeMillis();
prevExecutionMs = startedAtMs;
while (true) {
// check if the job was interrupted
if (Thread.interrupted()) {
return;
}
long now = System.currentTimeMillis();
// check if it's time to finish
if (now - startedAtMs > timeoutMs) {
break;
}
// check if it's time to run the action
if(now - prevExecutionMs > rateMs){
// run the action
action.run();
// update the executed time
prevExecutionMs = now;
}
}
}
// this getter could be used to get the running time
public double getTimeToDisplay() {
return (System.currentTimeMillis() - startedAtMs) / 1000D;
}
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Execution("exec", 0.5, new Runnable() {
#Override
public void run() {
System.out.println(new Date());
}
}));
//starts the thread
thread.start();
//waits to finish
thread.join();
System.out.println("Done!");
}
}
I am not sure that is what you expect, but:
public void run() {
try {
while(true) {
timeToDisplay++;
Thread.sleep(1);
}
} catch (Exception e) {
}
}
You may need to synchronize your get and set methods, depending on what you are trying to achieve.
Thread t1 = new Thread(new Execution(Name1,et1, new Runnable(){
#Override
public void run() {
p1RunningState.setText("Running");
}
}));
t1.start();
if(!(t1.isAlive())){
p1RunningState.setText("Stopped");
}
t1.join();
Related
I know there are many frameworks for Scheduler as well as JDK's own Scheduler. I can't use any third party framework/API. The existing scheduler uses only Java API. It is as follows:-
public class Timer implements Runnable {
private Thread runner;
private int pause;
private Task task;
private boolean running;
public Timer(int pause, Task task) {
this.pause = pause;
this.task = task;
runner = new Thread(this, "Timer");
}
public void run() {
try {
while (running) {
task.run(); // long running task
synchronized (runner) {
runner.wait(pause);
}
}
} catch (InterruptedException ie) {
/* The user probably stopped the */
}
}
Interface and class:-
public interface Task {
void run();
}
public class TaskManager implements Task {
private static boolean firstRun = true;
private static Timer timer;
private static String lastRun;
public static void start(int interval) {
// stop any previous
if (timer != null) {
timer.stopTimer();
timer = null;
}
// Start a new one
TaskManager taskManager = new TaskManager ();
timer = new Timer(interval * 1000, taskManager );
timer.startTimer();
}
public void run() {
// long running code
}
public void setDelay(int p) {
pause = p;
}
public void startTimer() {
running = true;
runner.start();
}
public void stopTimer() {
running = false;
runner.interrupt();
}
}
From a servelet I call as:
private void startTaskManager() {
TaskManager.start(30);
}
My requirements that it will perform task in a thread in the run() method. There are many tasks that will be picked one after another from the database.
The above implementation has some issues. On the above implementation, it has own interface Task and implemented own Timer.
I think there is another better way to achieve this scheduler. Please suggest me.
Please find my requirement here.I have a InvokeTimer class which invokes TimerClass for every sec/min/hour.In the runnable of TimerClass in need to execute a logic when timer is triggered for every sec i.e if its instance of stats1 and other logic if instance of stats2 if triggered for every minute,similary for an hour.Please help me.How do i do this?
public class TimerClass extends TimerTask{
#Override
public void run() {
if(stats1){
//logic
}else if(stats2){
//logic
}else{
//logic3
}
}
public class InvokeTimer {
TimerClass stats1 = new TimerClass();
TimerClass stats2 = new TimerClass();
TimerClass stats3 = new TimerClass();
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(stats1, 0, 1 * 1000);
timer.scheduleAtFixedRate(stats2, 0, 60 * 1000);
timer.scheduleAtFixedRate(stats3, 0, 24* 60 * 1000);
}
Honestly, I think your best bet here might be to make your timers anonymous classes which each support a run() method. For instance, this would be a TimerClass that beeped every second:
TimerClass stats1 = new TimerClass() {
#Override
public void run() {
java.awt.Toolkit.getDefaultToolkit().beep();
}
};
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(stats1, 0, 1 * 1000);
You could have one for each stats, with unique logic within each stats's method.
Checking which version of stats is running all within the same method isn't an incredibly reliable way to set things up, but if you're dead set on it, I suppose you could make your TimerClass objects instance variables, then in your if-statements say
if(this.equals(stats1))
//logic
but I think you'd need both classes in the same .java file for TimerTask to see them. I'd stick with the former approach if I were you.
You can find more on anonymous classes here: https://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
You can put common functionality in base class.
Extends all your specific stats classes to base class.
Multiple if else statement clutters the code.
Why ScheduledThreadPoolExecutor is better than Timer is explained here.
Try to use ScheduledThreadPoolExecutor as it is best for your usecase.
Example.
public class ScheduleSimulator {
public static void main(String[] args) {
final ScheduledExecutorService executor = Executors
.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(new Stats1("X"), 0, 1, TimeUnit.SECONDS);
executor.scheduleAtFixedRate(new Stats2("Y"), 0, 1, TimeUnit.MINUTES);
executor.scheduleAtFixedRate(new Stats3("Z"), 0, 1, TimeUnit.HOURS);
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
#Override
public void run() {
executor.shutdownNow();
}
}));
}
}
class CommonStats {
// Common functionality.
}
class Stats1 extends CommonStats implements Runnable {
private String name;
public Stats1(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public void run() {
try {
System.out.println("Doing a task during : " + name + " - Time - "
+ new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Stats2 extends CommonStats implements Runnable {
private String name;
public Stats2(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public void run() {
try {
System.out.println("Doing a task during : " + name + " - Time - "
+ new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Stats3 extends CommonStats implements Runnable {
private String name;
public Stats3(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public void run() {
try {
System.out.println("Doing a task during : " + name + " - Time - "
+ new Date());
} catch (Exception e) {
e.printStackTrace();
}
}
}
In a web server i wrote, each request invokes a list of actions. Some of these actions aren't as critical as others, so I would like to run them in a background thread.
Also, since they aren't that important I don't care if one of them fails seldomly, and I don't want them to take up a thread forever, so other threads would be available to process the next batch.
So, I would like to have a thread pool (e.g.: 10 threads) and hand out a thread to each background task like this. Limit each thread to 1 second, and if it doesn't finish by that time, just kill it, and be available for the next task to come in.
How would I go about doing this ?
So far, this is what I have :
public class AsyncCodeRunner {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public void Run(Callable<Void> callableCode, int timeout) {
final int threadTimeout = 10;
Future<Void> callableFuture = executor.submit(callableCode);
try {
callableFuture.get(threadTimeout, TimeUnit.SECONDS);
} catch (Exception e) {
logger.Info("Thread was timed out", e);
}
}
}
And I want to use this class like this :
public void processRequest(RequestObject request) {
// do some important processing
// throw some less important processing to background thread
(new AsyncCodeRunner()).Run(new Callable<Void> () {
#Override
public Void call() throws Exception {
// do something...
return null;
}
}, 1); // 1 second timeout
// return result (without waiting for background task)
return;
}
Will this work like I want it to ? Or how should I change it so it would ?
And what happens if I call Run() but there are no available threads in the threadpool to hand out ?
I think your primary problem with this rather elegant idea is that you are only timing out on the get of the Future, you are not actually aborting the process once it times out, you are just giving up waiting for it. The issue becomes even more complex when you realise that you may even time out when the process hasn't even started - it is just still in the queue.
Perhaps something like this would be effective. It does require two threads but a TimerTask thread should consume very little.
public class RunWithTimeout {
public RunWithTimeout(Runnable r, long timeout) {
// Prepare the thread.
final Thread t = new Thread(r);
// Start the timer.
new Timer(true).schedule(new TimerTask() {
#Override
public void run() {
if (t.isAlive()) {
// Abort the thread.
t.interrupt();
}
}
}, timeout * 1000);
// Start the thread.
t.start();
}
}
class WaitAFewSeconds implements Runnable {
final long seconds;
WaitAFewSeconds(long seconds) {
this.seconds = seconds;
}
#Override
public void run() {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ie) {
System.out.println("WaitAFewSeconds(" + seconds + ") - Interrupted!");
}
}
}
public void test() {
new RunWithTimeout(new WaitAFewSeconds(5), 3);
new RunWithTimeout(new WaitAFewSeconds(3), 5);
}
Here's an alternative that only uses one extra thread.
public class ThreadKiller implements Runnable {
DelayQueue<WaitForDeath> kill = new DelayQueue<>();
private class WaitForDeath implements Delayed {
final Thread t;
final long finish;
public WaitForDeath(Thread t, long wait) {
this.t = t;
this.finish = System.currentTimeMillis() + wait;
}
#Override
public long getDelay(TimeUnit unit) {
return unit.convert(finish - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
#Override
public int compareTo(Delayed o) {
long itsFinish = ((WaitForDeath) o).finish;
return finish < itsFinish ? -1 : finish == itsFinish ? 0 : 1;
}
}
#Override
public void run() {
while (true) {
try {
WaitForDeath t = kill.take();
if (t.t.isAlive()) {
// Interrupt it.
t.t.interrupt();
}
} catch (InterruptedException ex) {
// Not sure what to do here.
}
}
}
public void registerThread(Thread t, long wait) {
// Post it into the delay queue.
kill.add(new WaitForDeath(t, wait));
}
}
public void test() throws InterruptedException {
// Testing the ThreadKiller.
ThreadKiller killer = new ThreadKiller();
Thread killerThread = new Thread(killer);
killerThread.setDaemon(true);
Thread twoSeconds = new Thread(new WaitAFewSeconds(2));
Thread fourSeconds = new Thread(new WaitAFewSeconds(4));
killer.registerThread(twoSeconds, 5000);
killer.registerThread(fourSeconds, 3000);
killerThread.start();
twoSeconds.start();
fourSeconds.start();
System.out.println("Waiting");
Thread.sleep(10 * 1000);
System.out.println("Finished");
killerThread.interrupt();
}
You need to start timer when the thread runs. Then no thread in waiting state will be killed. Here is the sample from this thread:
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class PoolTest {
class TimeOutTask extends TimerTask {
Thread t;
TimeOutTask(Thread t) {
this.t = t;
}
public void run() {
if (t != null && t.isAlive()) {
t.interrupt();
}
}
}
class MyRunnable implements Runnable {
Timer timer = new Timer(true);
public void run() {
timer.schedule(new TimeOutTask(Thread.currentThread()), 1000);
try {
System.out.println("MyRunnable...");
Thread.sleep(10000);
} catch (InterruptedException ie) {
System.out.println("MyRunnable error...");
ie.printStackTrace();
}
}
}
public static void main(String args[]) {
new PoolTest();
}
public PoolTest() {
try {
ExecutorService pe = Executors.newFixedThreadPool(3);
pe.execute(new MyRunnable());
} catch (Exception e) {
e.printStackTrace();
}
}
}
I cannot figure it out, how can I wake up RecursiveTasks, invoked by ForkJoinPool, when these tasks are on hold by wait method. Here is my simple example with the method MainRecursionClass.resume which is incorrect (does not wakes up RecursiveTasks).
public class Program {
public static void main(String[] args) {
Program p = new Program();
final MainRecursionClass mrc = p.new MainRecursionClass();
//Thread outputs integers to simulate work
new Thread() {
public void run() {
mrc.doJob();
}
}.start();
//Thread performs wait and notify on MainRecursionClass object
p.new PauseResume(mrc).start();
}
/**
*
* This class performs suspend and resume operations to the MainRecursionClass class object
*
*/
private class PauseResume extends Thread {
private MainRecursionClass rv;
public PauseResume(MainRecursionClass rv) {
this.rv = rv;
}
#Override
public void run() {
while(!isInterrupted()) {
try {
sleep(4000);
rv.suspend();
sleep(8000);
rv.resume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class MainRecursionClass {
private boolean pause = false;
private MyRecursive rv;
public void doJob() {
rv = new MyRecursive(0, 100000);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(rv);
}
public void suspend() {
pause = true;
System.out.println("Suspended");
}
/**
* This method is incorrect. It should wake up all MyRecursive instances to continue their work.
*/
public synchronized void resume() {
pause = false;
notifyAll();
System.out.println("Resumed");
}
private class MyRecursive extends RecursiveTask<Object> {
private static final long serialVersionUID = 1L;
private int start;
private int length;
private int threshold = 15;
public MyRecursive(int start, int length) {
super();
this.start = start;
this.length = length;
}
protected void computeDirectly() throws Exception {
for (int index = start; index < start + length; index++) {
//PAUSE
synchronized (this) {
try {
while(pause) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//PAUSE
//some output to simulate work...
System.out.println(index);
Thread.sleep(1000);
}
}
/**
* Recursion
*/
#Override
protected Object compute() {
if (length <= threshold) {
try {
computeDirectly();
} catch (Exception e) {
return e;
}
return null;
}
int split = length / 2;
invokeAll(new MyRecursive(start, split),
new MyRecursive(start + split, length - split));
return null;
}
}
}
}
You should not use wait/notify in the tasks running on a thread pool. If your pool is bounded, then it may cause thread starvation (a form of deadlock). If it is unbounded, too many threads can be created and main memory exhausted.
Instead, you should split your task in 2 (or more) and start subtasks according to their starting conditions. When you want a task to wait(), then refactor it so that current subtask exits, and next subtask is prepared to run.
Finally I came to this solution: I created List<MyRecursive> list = new ArrayList<>(); object in MainRecursionClass and added every MyRecursive instance, created recursively, in the list. The class MyRecursive has new method:
public synchronized void resume() {
notify();
}
When, the method MainRecursionClass.resume(), which wakes up the threads, looks like this:
public void resume() {
System.out.println("Resumed");
pause = false;
for(MyRecursive mr : list) {
if(mr != null)
mr.resume();
}
}
}
Very recently I've asked this question, but wasn unable to fix this. So I have a thread hunter (2 of them actually), who "goes off to catch wild boars". He stores these boars in a container Fridge. He will continue to do so until his working hours expire. However, in case the Fridge is full he has to wait. The aim is to wait until a wild boar is removed from the fridge, but if it takes more then 5 seconds of waiting test must be terminated. So everything works except one thing. After running test and interrupting these threads, the program still continues to run. So how do I completely terminate/stop these threads?
TEST CLASS (main)
class Test {
public static void main(String[] args) {
test1();
}
public static void test1() {
Fridge fridge = new Fridge(4);
Hunter hunter1 = new Hunter("hunter1", 4, fridge);
Hunter hunter2 = new Hunter("hunter2", 7, fridge);
Thread hunterThread1 = new Thread(hunter1);
Thread hunterThread2 = new Thread(hunter2);
hunterThread1.start();
hunterThread2.start();
try { Thread.sleep(1000); } catch (InterruptedException e) {}
hunterThread1.interrupt();
hunterThread2.interrupt();
System.out.println(fridge.getSize());
System.out.println(hunter1.getWorkTime());
System.out.println(hunter2.getWorkTime());
}
}
HUNTER CLASS
class Hunter extends Worker {
private int workTime;
private Fridge fridge;
public Hunter(String name, int workTime, Fridge fridge) {
super(name);
this.workTime = workTime;
this.fridge = fridge;
}
public int getWorkTime() {
return workTime;
}
public void run() {
while (workTime > 0) {
/** Each hunt takes a random amount of time (1-50 ms) **/
try { Thread.sleep(workGen()); } catch (InterruptedException e) {}
/** Add new wild boars **/
try { fridge.add(new WildBoar()); } catch (InterruptedException e) {}
workTime--;
/** If thread is interupted break the loop **/
if( Thread.currentThread().isInterrupted()){
break;
}
}
}
}
FRIDGE CLASS
import java.util.Stack;
class Fridge extends Storage {
private Stack<WildBoar> boars;
public Fridge(int cap) {
super(cap);
boars = new Stack<WildBoar>();
}
public int getCap() {
return cap;
}
public int getSize() {
return boars.size();
}
public boolean hasFreeSpace() {
if ( boars.size() < cap )
return true;
else
return false;
}
public synchronized void add(WildBoar boar) throws InterruptedException {
/** If there's no free space available wait **/
while ( !hasFreeSpace() ) {
wait();
}
/** Once there's free space available add new item **/
boars.add(boar);
}
public synchronized WildBoar remove() {
return boars.pop();
}
}
ADDITIONAL CLASSES FOR COMPILING:
abstract class Worker implements Runnable {
private String name;
public Worker(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int workGen() {
return 1 + (int)(Math.random() * (50 - 1));
}
}
class WildBoar {
public WildBoar() {}
}
abstract class Storage {
protected int cap;
public Storage(int cap) {
this.cap = cap;
}
public int getCap() {
return cap;
}
}
After you interrupt() the thread which is currently waiting, the native wait method will actually reset the interruption flag. So when you evaluate the isInterrupted() here, it is actually reset and will appear as not interrupted.
if( Thread.currentThread().isInterrupted()){
break;
}
You will have to re-interrupt the thread after an interruption occurs during the waiting
public synchronized void add(Object boar) {
/** If there's no free space available wait **/
while (!hasFreeSpace()) {
try{
wait();
}catch(InterruptedException e){
Thread.currentThread().interrupt();
return; //or rethrow
}
}
/** Once there's free space available add new item **/
boars.add(boar);
}
Currently, the run method in your Hunter thread is discarding interruptions:
try { fridge.add(new WildBoar()); }
catch (InterruptedException e) {}
Thus, nothing happens when you later check for interruptions
if( Thread.currentThread().isInterrupted()){
break;
}
To correct this, you need to set the thread's interrupt status:
try { fridge.add(new WildBoar()); }
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Summary - ignoring the InterruptedException resets the interrupt status. If you don't or re-throw it or break, then you will need to set the interrupt status manually.