Handling regular jobs with possible manual start in Java - java

I'm trying to solve a problem similar to downloading new mails from mail servers by mail client. I have a task, which is performed regularly (next iteration is 10 minutes after the last one ends for example) but there is also a possibility to run the task manually.
When I am trying to run the job manually and job is not running at this moment (is appointed for later), I cancel the appointment and schedule it for now. When the job is already running I do not cancel it, but wait until it finishes and run it again. But only one task can wait this way.
My problem is that I do not know how to synchronize the jobs to make it thread safe and make sure that job never runs twice at the same time.
To make it more clear. The main problem is that simple asking if the job is running and deciding based on what I get is not enough, because between the question and action the situation can change. It is a short span but the probability is not zero. And the same problem is with deciding if I should run the job again at the end of his run. If my decision is based on the value of some variable or some other if clause, then between testing its value and performing some action, some other thread can change it and I can end up with two scheduled jobs or none at all.

Have you considered using a DelayQueue?
To make your job run now you just need to persuade it to return 0 form getDelay(TimeUnit unit).

The main way to do that check you are telling about is to check, to lock and after that to repeat the same check:
public class OneQueuedThread extends Thread {
static int numberRunning =0;
public void run() {
if (numberRunning<2) {
synchronized (OneQueuedThread.class){
if (numberRunning<2) {
numberRunning++;
// ---------------your process runs here
numberRunning--;
}
}
}
}
}
So, only one attempt to run the thread while it is already running will wait until the end of the running thread and start after it.
As for scheduling, let's use the TimerTask features:
public class ScheduledTask extends TimerTask {
ScheduledTask instance;
/**
* this constructor is to be used for manual launching
*/
public void ScheduledTask(){
if (instance == null){
instance = this;
} else {
instance.cancel();
}
instance.run();
}
/**
* This constructor is to be used for scheduled launching
* #param deltaTime
*/
public ScheduledTask(long deltaTime){
instance = this;
Timer timer = new Timer();
timer.schedule(instance, deltaTime);
}
public void run() {
OneQueuedThread currentTread;
currentTread = new OneQueuedThread();
currentTread.start();
}
}

Related

Javafx - Concurrently reusing javafx Service<>

On JavaFx a reusable task is usually implemented on a javafx.concurrent.Service<>.
The question is: how to manage multiple UI interactions that triggers the Service multiple times?
Approach 1 - restart():
I could use service.restart(), but it cancels the running task and starts a new one. This is not the desired result, as I do not wish to cancel the first one.
Approach 2 - start():
To be able to use start() more than once, I would have to do this:
if(!isRunning()) {
reset();
start();
}
But if isRunning() is true, the second run is ignored.
I want to block the second run until the first one finishes, so no UI interaction is lost. So I wish to block or enqueue the tasks.
How would this be accomplished ?
If you want to stop users from trying to run the Service two or more times at once, simply disable all the UI nodes that launch the Service while it's running. One way of doing this is to bind the disable property of the Node to the running property of the Service.
If you want to queue up executions then it depends on what the Service requires. For instance, does it need any input? If not, just have some requests variable and increment/decrement it as needed.
public class Controller {
private int requests;
private Service<Object> service = new Service<>() {
#Override
protected Task<Object> createTask() {
// create and return Task...
}
#Override
protected void succeeded() {
if (requests > 0) {
requests--;
restart();
}
}
};
#FXML
private void startService() {
if (service.isRunning()) {
requests++;
} else {
service.start();
}
}
}
If the Service (or more specifically, the Task) does need input you'd still do something similar. Instead of using an int tracking the number of requests, however, you'd use a Queue (or some other similar object) that contains the needed information for each Task. When the Service completes and the Queue is not empty, restart the Service and grab the next element.

Run a task continuously without delay inside a Java TimerTask

How do I run a specific set of instructions inside the TimerTask continuously without delay for a set amount of time ? Below are the codes I am attempting to implement the above.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Test started at: " + new Date());
// Do something continuously without delay
System.out.println("Test finished at: " + new Date());
}
}, 0);
The second parameter to the schedule method is the time to begin the timer task (or delay relative to now), not the length of time that the timer will execute for.
It's not completely clear from your question but I'm assuming you want the task to start and stop at particular times (or delays relative to now) in the future. If so, the way I would approach this is to create a Thread that does the task you need. Since a TimerTask is a Runnable that is executed as a Thread once the Timer starts it, you can just use an instance of that TimerTask. Ensure that Runnable contains a settable field like running. In that Thread, run your task in a while loop like this:
public void run() {
while(running) { /* do my task */ }
}
Then, use one Timer to schedule the Runnable to start at the time you need. Use another Timer to set the running parameter of the same Thread to false at the time you want it to stop. The running parameter should be volatile to ensure that changes to it from the second timer Thread are seen by the first timer Thread immediately. So it would look something like this (not tested):
class StoppableTimerTask extends TimerTask {
private volatile boolean running = true;
public void stopRunning() { this.running = false; }
public void run() {
while(running) { /* do my task */ }
}
}
final StoppableTimerTask task = new StoppableTimerTask();
timer.schedule(task, startTime);
timer.schedule(new TimerTask() {
public void run() {
task.stopRunning();
}
}, stopTime);
Depending on what your "something" is, you may also want to look into Thread interrupts. For example, if it is doing blocking IO, your code won't loop and check the running value until the blocking IO completes. Interrupting the thread (may) cause that to happen. See http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#interrupt--. This may or may not work, and it can be tricky to get right, so if you need this Thread to exit as close to the desired time as possible, prefer running blocking I/O and similar operations with smaller timeouts so that the thread can check whether it should continue to run more often.
UPDATE: As per the comment indicating that the task should start right away, it becomes even simpler. The initial task doesn't even need to extend TimerTask -- it can just be a regular Thread that is started immediately. The timer is only needed to stop it at the specified future time.

How to change my Thread implementation to use ExecutorService

I had been making a game, and was using Threads in my program to carry out tasks. So let me explain the scenario a bit. I have a BattleManager class which implements Runnable and keep looping in the battle queue for battles, if there are any.
#Override
public void run() {
while(serverRunning){
synchronized (battleQueue) {
for(Battle battle : battleQueue){
if(battle != null){
if (battle instanceof WildBattle) {
if(!((WildBattle) battle).isBattleOver()){
((WildBattle) battle).tryExecuteBattleTurn();
}else{
battleQueue.remove(battle);
battle = null;
}
}
}
}
}
try {
Thread.sleep(3);
} catch (InterruptedException e)
e.printStackTrace();
}
}
currentThread = null;
}
Then I check if battle is not over, and if not I try to execute the battle turn. Since there can be more than 100 battles running at the same time and there are complex calculations inside every battle, I inside WildBattle class spawn a child thread to execute the task, so that the battles run in parallel.
Here is the method which is invoked inside wild battle class, which spawns a new thread.
public void tryExecuteBattleTurn() {
if (!isBattleTurnRunning && battleThread == null) {
battleThread = new Thread(new Runnable() {
#Override
public void run() {
//long startTime = System.currentTimeMillis();
executeBattle();
battleLog.setBattleLog("");
battleThread = null;
//System.err.println("Total execution time : " +(System.currentTimeMillis() - startTime));
}
}, "Battle thread");
battleThread.start();
}
}
Now the main question is, I want to learn about executor service and I read at few places that it is always better to use executor service rather than spawning new child threads. How can I change this to use executor service.
I am not sure though. I am not a java expert and still learning the language so spare me if you see something is wrong, and please let me know if I can change anything to make it more efficient.
Let me know if you are not clear about anything.
I'll show you a basic example and you'll manage how to integrate it with your code
First you create ExecutorService somewhere in your application.
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
You should choose NUMBER_OF_THREADS based on your application needs. Threads are not created immediately - only when you submit a task to service and there are no available threads for it. If all NUMBER_OF_THREADS are busy, task will wait in queue until one of the threads will be able to handle it. ExecutorService will reuse threads, this will save time on thread instantiation and is a generally good concept to work with threads.
Then you manage how to access executor service from your battles. Then, when you need to perform an asynchronous work you submit task to service:
executorService.submit(new Runnable() {
#Override public void run() {
// your code here
}
}
If your application has a lifecycle and can be somehow shutdown, you'd like to shutdown ExecutorService as well. There are two options - shutdown() and shutdownNow(), first one waits for all current tasks to be executed, second one performs shutdown immediately and returns list of tasks that were not completed.
As was mentioned in comments, you should figure out how to preserve model state and organize thread synchronization based on your real situation.

java- How to check whether scheduler is working

I am running a scheduled task in the web application using the java SingleThreadScheduledExecutor
The problem I have is - How do I identify whether the scheduler is still running and has not crashed?
Is there a better way of doing it rather than having another scheduler to check this particular scheduler
there is actually a way to check
public class TaskSchedulerService{
private final ThreadPoolTaskScheduler taskScheduler; //initialize it here or in constructor
private Map<String,ScheduledFuture<?>> scheduleMap = new ConcurrentHashMap<>();
public TaskSchedulerServiceImpl() {
this.schedulerName = schedulerName;
taskScheduler.initialize();
}
public boolean isScheduled(String taskId) {
final ScheduledFuture<?> exits = scheduledTasks.get(taskId);
return exits != null && exits.isDone();
}
public ScheduledFuture<?> schedule(String taskId, Runnable task, Date date) {
ScheduledFuture<?> scheduled = scheduleMap.get(taskId);
if (scheduled==null ) {
ScheduledFuture<?> future = taskScheduler.schedule(task, date);
scheduleMap.put(taskId, future);
return future;
} else {
// log it is already scheduled
return scheduled;
}
}
i know it is too late but i hope others can get benefit from it
The logic behind the implementation is whenever you are trying to schedule a task, you will have to add it to the map with the taskId as well, in this case it is better to find any task if exists in MAP or if needed remove it as well as checking if that task is done or not
The answer depends on what your scheduler does really. For instance, you can produce a file or update a field in a db or such thing that can be checked and the time interval (from now to last update) can be calculated. In your case, if the time interval of file creation or db updated is more than half an hour this means the job did stop. But notice that scheduled jobs are meant to last forever like love.

How to stop threads in Java?

I have made a java program with GUI and I want a stop button functionality in which when a user clicks on the stop button, the program must be stopped.
In my program, the main thread starts other 10 threads and I want that whenever the stop button has been clicked all the 10 threads must be stopped before the main thread.
Second, I also want that whenever any thread of those 10 threads is stopped, it must first close all the resources it had opened before like connection to a database etc.
I have implemented the code as answered by ........
Now there is one problem.
My thread class is like this:
public class ParserThread implements Runnable {
private volatile boolean stopped = false;
public void stopTheThread() {
stopped = true;
}
:
:
}
And below is the main thread that starts 10 threads from the function start()
public class Main() {
Thread [] threads;
public void start() {
for(int i = 0; i < 10; i++) {
threads[i] = new Thread(new ParserThread());
}
}
public void stop() {
// code to stop all the threads
}
}
Now I want to call the stop method of the ParserThread to set "stopped = true" to stop the thread. I want this thing to be done for all the 10 threads.
How can I call that stop method. I want it to be done in the stopAllThreads() method of the Main class.
Generally speaking, the way to do this is to have each of the other threads periodically check a flag. Often background threads loop, waiting for work - they just have to check the flag each time they go round a loop. If they're using Object.wait() or something similar to be told that there's more work, the same notification should be used to indicate that the thread should stop too. (Don't just spin until you're stopped - that will suck CPU. Don't just use sleep - that will delay termination.)
That allows all threads to terminate cleanly, releasing resources appropriately. Other options such as interrupt() and the deprecated destroy() method are much harder to control properly, IMO. (Interrupting a thread is better than hard-aborting it, but it has its own set of problems - such as the interruption is only processed at certain points anyway.)
EDIT: In code, it would look something like:
// Client code
for (Task task : tasks) {
task.stop();
}
// Threading code
public abstract class Task implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
protected boolean shouldStop() {
return stopped;
}
public abstract void run();
}
Your tasks would then subclass Task. You would need to make it slightly more complicated if you wanted the stop() method to also notify a monitor, but that's the basic idea.
Sample task:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
I don't think the answer solve the issue. here the code:
public class SomeTask extends Task {
public void run() {
while (!shouldStop()) {
// Do work
}
}
}
But how to handle if the "Do work" hang and does not return? In this case, the while cannot check the flag. The Thread still cannot stop.
The possible solution to this might be using Process.
Have a controller object which has a flag whether the threads should stop or not and each thread checks the controller periodically and exits if stop button is clicked (for example if you are transferring a file, then after each block is received/sent, check if stop is clicked).

Categories