How could I run two of my schedulers in parallel? - java

I have been wanting for a long time to add schedulers to my API. So I set a class for the purpose. Here it is.
public abstract class SyncScheduler extends Scheduler {
private Thread thread = null;
private boolean repeating = false;
#Override
public synchronized void runTask() {
thread = new Thread(this);
thread.start();
}
#Override
public synchronized void runTaskLater(long delay) {
thread = new Thread(this);
try {
Thread.sleep(delay * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.run();
}
#Override
public synchronized void runRepeatingTask(long period) {
thread = new Thread(this);
repeating = true;
while (!thread.isInterrupted()) {
thread.run();
try {
Thread.sleep(period * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public synchronized void cancel() {
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
}}
Scheduler just implements Runnable.
The problem is that whenever I try to create 2 or more Schedulers, the second one never starts until the first one is finished! For example if I have on Scheduler that runs every X seconds and I have another one the cancels it, the one that cancels the first one never starts! This is the problem.
How could I run two of these schedulers in parallel?
Also these are my two test main classes.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}}
And here's the second one.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
}}
The first one outputs "It works." repeatedly until I force stop the test.
The second one gives me "It works." for once, then It gives me "Stopped." and with it and exception.

You are using the thread object wrongly.
To start a Runnable object (in this case, Thread object) in a different thread, the object must call start() method. You are using run() method, which just calling the method in the same thread without creating a new thread.
Try to change run() in SyncScheduler.runRepeatingTask and SyncScheduler.runTaskLater.
Also, I just noticed in your cancel() method:
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
This would make the method throw exception if thread started. I think it should be if (thread == null || !repeating) {

Related

How to triggerShutdown a Guava AbstractScheduledService?

I'm using a few services inheriting from the AbstractScheduledService, which get managed by a ServiceManager. Everything works fine, but now, there's a service whose runOneIteration takes a rather long time, and as the result, my process takes too long to terminate (more than five seconds).
There are other services inheriting from AbstractExecutionThreadService, which had a similar problem, which I could solve via
#Override
protected final void triggerShutdown() {
if (thread != null) thread.interrupt();
}
and storing private volatile thread in the run method. However, there's no triggerShutdown for AbstractScheduledService as stated in this issue.
I already considered alternatives like making runOneIteration do less work, but it's both ugly and inefficient.
I can't override stopAsync as it's final and I can't see anything else. Is there a hook for doing something like this?
Can you work with this? Was there any reason you couldn't add a triggerShutdown yourself?
class GuavaServer {
public static void main(String[] args) throws InterruptedException {
GuavaServer gs = new GuavaServer();
Set<ForceStoppableScheduledService> services = new HashSet<>();
ForceStoppableScheduledService ts = gs.new ForceStoppableScheduledService();
services.add(ts);
ServiceManager manager = new ServiceManager(services);
manager.addListener(new Listener() {
public void stopped() {
System.out.println("Stopped");
}
public void healthy() {
System.out.println("Health");
}
public void failure(Service service) {
System.out.println("Failure");
System.exit(1);
}
}, MoreExecutors.directExecutor());
manager.startAsync(); // start all the services asynchronously
Thread.sleep(3000);
manager.stopAsync();
//maybe make a manager.StopNOW()?
for (ForceStoppableScheduledService service : services) {
service.triggerShutdown();
}
}
public class ForceStoppableScheduledService extends AbstractScheduledService {
Thread thread;
#Override
protected void runOneIteration() throws Exception {
thread = Thread.currentThread();
try {
System.out.println("Working");
Thread.sleep(10000);
} catch (InterruptedException e) {// can your long process throw InterruptedException?
System.out.println("Thread was interrupted, Failed to complete operation");
} finally {
thread = null;
}
System.out.println("Done");
}
#Override
protected Scheduler scheduler() {
return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
}
protected void triggerShutdown() {
if (thread != null) thread.interrupt();
}
}
}

handle multiple infinite tasks in a single thread? P.S run one task at a time and control its task behavior(i.e starting/stoping task) from outside

I want to make a single thread which would contain 3 infinite tasks.
I want one task to run at a time and start/stop running task when required.
For example first I want task 1 to run, then I want task 2 to run but after stopping task 1 and again I want task 1 to run but after stopping of task 2 and so on.
Infinite task needs to check some condition and if that condition is satisfied perform some operations and if not satisfied sleep for few seconds and after wake up perform the above same operations again.
Infinite Runnable task looks some thing like this:
new Runnable(){
while(1){
if(TaskQueue.getInstance().size()<= 100){
TaskQueue.getInstance().push("add command to the end of queue");
}else{
try {
Thread.sleep(10000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Any help would be appreciated?
Edit : I modified my question. I want a continuous single running thread(some thing like looper ) to monitor 3 infinite tasks and control this single continuous running thread tasks from outside.
Use this for start/stop thread in real-time:
class MyThread extends Thread {
private volatile boolean running = true; // Run unless told to pause
...
#Override
public void run() {
// Only keep painting while "running" is true
// This is a crude implementation of pausing the thread
while (true) {
if (Thread.currentThread().isInterrupted()) {
return;
}
if (running) {
//Your code
} else yield;
}
}
public void pauseThread() throws InterruptedException {
running = false;
}
public void resumeThread() {
running = true;
}
}
For pause thread use this:
myThread.pauseThread();
For resume thread use this:
myThread.resumeThread();
For stop thread use this (Not recommended):
myThread.stop();
For currently stop thread use this:
myThread.interrupt();
You must use a class like Thread that already implements Runnable.
new Thread(){....};
And the way it works it's:
Thread t = new Thread(){.....};
t.start();
t.stop();
You could also initialize a new thread, like:
Thread exampleThread = new thread();
After this you can start it at any point in your code by:
exampleThread.start();
you can use Semaphore,
to Manage the amount of signal.
private final static Semaphore semaphore = new Semaphore(0);
public static void main(String[] args) throws Exception {
//入口
threadTest();
}
public static void thread1() {
try{
//…… some code
}
finally{
semaphore.release();
}
}
public static void thread2() {
semaphore.acquire(1);
}
The question is my first answer,thanks.
I finally made my task scheduler. The API of which looks something like this:
TaskScheduler taskScheduler = TaskScheduler.getInstance();
taskScheduler.startTaskOne();
taskScheduler.stopTaskOne();
taskScheduler.startTaskTwo();
taskScheduler.stopTaskTwo();
Runs one task at a time (because I used Executors.newSingleThreadExecutor()).
We can control the execution of the task from outside:
public class TaskScheduler {
private static ExecutorService mTaskRunningService;
private static TaskScheduler mInstance;
private Future mFirstTaskFuture = null;
private Future mSecondTaskFuture = null;
static {
configure();
}
private static void configure() {
mTaskRunningService = Executors.newSingleThreadExecutor();
}
public static TaskScheduler getInstance() {
if (mInstance == null) {
mInstance = new TaskScheduler();
}
return mInstance;
}
private Runnable mTaskOneRunnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
/** stop this single thread (i.e executing one task at time) service if this thread is interrupted
* from outside because documentation of {#link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
* says we need to do this*/
if (Thread.currentThread().isInterrupted()) {
return;
}
// task one work.......
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
private Runnable mTaskTwoRunnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
/** stop this single thread (i.e executing one task at time) service if this thread is interrupted
* from outside because documentation of {#link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
* says we need to do this*/
if (Thread.currentThread().isInterrupted()) {
return;
}
// task two work......
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
public synchronized void startTaskOne() {
if (mFirstTaskFuture == null) {
// start executing runnable
mFirstTaskFuture = mTaskRunningService.submit(mTaskOneRunnable);
}
}
public synchronized boolean stopTaskOne() {
if (mFirstTaskFuture != null) {
// stop general reading thread
mFirstTaskFuture.cancel(true);
// cancel status
boolean status = mFirstTaskFuture.isDone();
// assign null because startTaskOne() again be called
mGeneralFuture = null;
return status;
}
return true;
}
public synchronized void startTaskTwo() {
if (mSecondTaskFuture == null) {
// start executing runnable
mSecondTaskFuture = mTaskRunningService.submit(mTaskTwoRunnable);
}
}
public synchronized boolean stopTaskTwo() {
if (mSecondTaskFuture != null) {
// clear task queue
mTaskQueue.clearTaskQueue();
// stop 22 probes reading thread
mSecondTaskFuture.cancel(true);
// cancel status
boolean status = mSecondTaskFuture.isDone();
// assign null because startTaskTwo() again be called
mSecondTaskFuture = null;
return status;
}
return true;
}
}

Access synchronized method from another thread using same instance

I've a core method in my project which I need it to be synchronized in order not to be accessed twice at the same time, and hence I have a thread which uses an instance from this class to access this method, but inside this thread I need to have a long life loop to be used to access the same method with a fixed value so I have to use another thread in order to allow the first thread to move on and complete it's duties, but for sure the method doesn't run from that second thread using the same instance used in the first thread, and somehow I can't instantiate another instance from the class as I have to use this instance exactly, so how to overcome this problem.
below is the problem translated to java:
public class ClassOne {
synchronized public void my_method(int number) {
// Do some Work
}
}
public class ClassTwo {
private void some_method() {
Thread one = new Thread(new Runnable() {
#Override
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
boolean running = true;
private void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
#Override
public void run() {
while (running) {
class_one.my_method(1); // won't run
Thread.sleep(10000);
}
}
});
two.start();
}
}
Actual problem overview:
my_method --- > is to send UDP packets.
the method has to be synchronized otherwise I'll get the socket is already open exception when trying to use it more than once repeatedly.
at some point, I have to send a KeepAlive message repeatedly each 10 seconds, so, I have to launch a separate thread for that which is thread two in run_loop method.
Putting something that will compile and work. I don't see why you need this function to be synchronized. Check the output for this program...The second thread access this method only when the first thread is done accessing (unless you have missed adding some additional code).
class ClassOne {
int criticalData = 1;
synchronized public void my_method(int number) {
// Do some Work
criticalData *= 31;
System.out.println("Critical data:" + criticalData + "[" + Thread.currentThread().getName() + "]");
}
}
class ClassTwo {
boolean running = true;
public void some_method() {
Thread one = new Thread(new Runnable() {
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
public void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
public void run() {
while (running) {
class_one.my_method(1); // won't run
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
two.start();
}
}
public class StackExchangeProblem {
public static void main(String[] args) {
ClassTwo two = new ClassTwo();
two.some_method();
}
}

Running asynchronous code in java with timeout

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();
}
}
}

How can I start, pause and resume my threads? (by extending thread from classes)

Essentially, what I want to do is start all my threads, pause them all, then resume them all, using the multithreading approach. I am just looking for a simple solution to this. I'm not sure if I have to use a timer or what. Right now when I run it, the threads are like being executed in random order (I guess the PC is just randomly picking which ones it wants to run at a certain time).
class ChoppingThread extends Thread
{
public void run()
{
for(int j=40;j!=0;j-=10)
System.out.println("Chopping vegetables...("+j+" seconds left)");
}
}
class MixingThread extends Thread
{
public void run()
{
for(int k=60;k!=0;k-=10)
System.out.println("Mixing sauces...("+k+" seconds left)");
}
}
class TenderizingThread extends Thread
{
public void run()
{
for(int j=50;j!=0;j-=10)
System.out.println("Tenderizing meat...("+j+" seconds left)");
}
}
class MultiThreadTasking
{
public static void main (String [] args)
{
ChoppingThread ct = new ChoppingThread();
MixingThread mt = new MixingThread();
TenderizingThread tt = new TenderizingThread();
System.out.println("\nWelcome to the busy kitchen.");
//putting threads into ready state
ct.start();
mt.start();
tt.start();
}
}
There are probably other ways to achieve the same result, but this is the simplest I can come up with off the top of my head (I know, sad isn't it)...
Basically, this is a special Runnable with some additional management functionality.
This basically contains a state flag that indicates the state of the task and a monitor lock
public class ThreadFun {
public static void main(String[] args) {
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.pauseTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.resumeTask();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
task.stopTask();
}
public enum TaskState {
Running,
Stopped,
Paused
}
public static class MyTask implements Runnable {
private static final Object PAUSED_LOCK = new Object();
private volatile TaskState state = TaskState.Running;
public void pauseTask() {
if (state == TaskState.Running) {
System.out.println("Paused...");
state = TaskState.Paused;
}
}
public void resumeTask() {
if (state == TaskState.Paused) {
state = TaskState.Running;
synchronized (PAUSED_LOCK) {
PAUSED_LOCK.notifyAll();
}
System.out.println("Resumed...");
}
}
public void stopTask() {
if (state == TaskState.Running || state == TaskState.Paused) {
state = TaskState.Stopped;
System.out.println("Stopped...");
}
}
public boolean isStopped() {
return state == TaskState.Stopped;
}
public boolean isPaused() {
return state == TaskState.Paused;
}
protected void doPause() {
synchronized (PAUSED_LOCK) {
while (isPaused()) {
try {
PAUSED_LOCK.wait();
} catch (InterruptedException ex) {
}
}
}
}
#Override
public void run() {
int index = 0;
while (!isStopped() && index < 1000) {
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
}
doPause();
index++;
System.out.println(index);
}
stopTask(); // Make sure the task is marked as begin stopped ;)
}
}
}
The main criteria is you will need to pool isStopped and doPause at appropriate points to ensure that they are begin implemented as required...
To coordinate them use a CyclicBarrier.
To launch them all at the same time use a CountDownLatch.
Google the two classes above for many examples and explanations.
To fully understand what is happening read the Java Concurrency In Practice book.
I believe you can accomplish this by using Object.wait and Thread.interrupt.
Object.wait blocks until notify is called. So
private boolean paused;
private Object waitObject;
...
public void run() {
for ... {
if (this.paused) { this.waitObject.wait(); }
...
public void pause() { this.paused = true; }
public void resume() { this.paused = false; this.waitObject.notify(); }
Then you can call pause to pause the thread.
Thread.interrupt can help with stopping.
private boolean paused;
...
public void run() {
for ... {
// interrupted() is different from interrupt()!
if (this.iterrupted()) { break; }
...
To stop it, you would call interrupt() from another thread.
This is the basic idea, but there's a lot of details to worry about here. For example, wait can throw an InterruptedException you'll need to handle. Also, wait is not guaranteed to return only after a notify. It can return randomly. Here is a pair of tutorials:
Wait: http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
Interrupt: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

Categories