Timer task to schedule multiple jobs - java

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

Related

Java sleep thread in Junit test case

I am trying to create a synchronized version of data and using junit to test my method. The code below is what I came so far. It works quite well if I put on the main method (the counter is increased one by one by each thread) but the test process will stop immediately. Is this the problem by using Thread.sleep() on a test case?
public void testGeneral() {
class SynchronizedData {
public AtomicBoolean lock = new AtomicBoolean(false);
public int counter = 0;
public void update() {
if(lock.compareAndSet(false, true)) {
counter++;
System.out.println(counter);
lock.set(false);
}
}
}
SynchronizedData data = new SynchronizedData();
class Handler implements Runnable {
String name;
public Handler(String name) {
this.name = name;
}
#Override
public void run() {
for(;;) {
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
System.out.println(e);
}
System.out.println(this.name);
data.update();
}
}
}
new Thread(new Handler("One")).start();
new Thread(new Handler("Two")).start();
}

Binding an API callback to an RxJava Observable

I'm trying make a reactive application that listens to a network socket on a separate thread for prices and got a bit stumped with how exactly to construct the Observable. Much of the interfaces I have are constrained by the API I am using and therefore cannot change. I distilled what I am trying to do as a test below, but I can't see how to fill in the body of the getPriceReactive() method such that the prices are printed on the console by the subscriber (see the comment in the code).
public class PriceObservableTest {
// This interface is defined externally and used by the API
private interface ITickHandler {
void priceReceived(double price);
}
// Stores the price (currently just one double for illustration)
private class Tick {
double price = Double.NaN;
}
// Implementation of handler called by API when it receives a price
private class TickHandler implements ITickHandler {
private final Tick tick;
TickHandler() { this.tick = new Tick(); }
#Override public void priceReceived(double x) { tick.price = x; }
}
// This class emulates the API delivering prices from the socket
private class PriceSource {
private final Thread thread;
PriceSource(final ITickHandler handler) {
thread = new Thread(new Runnable() {
final Random r = new Random();
#Override public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
handler.priceReceived(r.nextDouble() * 100);
} catch (InterruptedException e) {
break;
}
}
System.out.println("Price thread closed");
}
});
}
void subscribe() { thread.start(); }
void unsubscribe() { thread.interrupt(); }
}
#Test
public void simpleTest() throws Exception {
final ITickHandler handler = new TickHandler();
// Simulate some prices received periodically from a socket
PriceSource prices = new PriceSource(handler);
Observable<Tick> reactive = getPriceReactive(handler);
reactive.subscribe(new Subscriber<Tick>() {
#Override public void onCompleted() { }
#Override public void onError(Throwable e) { }
#Override public void onNext(Tick tick) {
System.out.println("Received price: " + tick.price);
}});
// Observe prices for 1 second. The subscriber should print them to console
prices.subscribe();
Thread.sleep(1000);
prices.unsubscribe();
}
// Returns an observable that reacts to price changes
private Observable<Tick> getPriceReactive(ITickHandler handler) {
return Observable.create(new Observable.OnSubscribe<Tick>() {
#Override public void call(Subscriber<? super Tick> subscriber) {
// How to call subscriber.onNext() whenever
// priceReceived() is called with a new price?
}
});
}
}
Somehow subscriber.onNext() needs to be called whenever the API calls priceReceived(), but I can't quite see how to achieve this. Of course I could store a reference to the subscriber in the TickHandler but this kind of defeats the purpose of having an Observable, doesn't it?
Transition to Observable in ITickHandler implementation. You are not controlling the subscriber(s) but the publisher
private class TickHandler implements ITickHandler {
private final Tick tick;
private final PublishSubject<Tick> priceSubject;
TickHandler() {
this.tick = new Tick();
this.priceSubject = PublishSubject.create();
}
#Override public void priceReceived(double x)
{
tick.price = x;
priceSubject.onNext(tick);
}
public Observable<Tick> priceReceivedObservable()
{
return priceSubject.asObservable();
}
}
And you can use it in your tests like:
final ITickHandler handler = new TickHandler();
PriceSource prices = new PriceSource(handler);
handler.priceReceivedObservable()
.subscribe(new Subscriber<Tick>() {
#Override public void onCompleted() { }
#Override public void onError(Throwable e) { }
#Override public void onNext(Tick tick) {
System.out.println("Received price: " + tick.price);
}});
I warn you, it's not tested since I don't do a lot of Java :)

About JAVA multithreading : How to create a process with extends Thread and implement Runnable

When I was reading the book "Thinking in JAVA", I found a question about JAVA multithreading.
class ThreadMethod {
private int countdown = 5;
private Thread t;
private String name;
public ThreadMethod(String name) {
this.name = name;
}
public void runTask() {
if (t == null) {
t = new Thread(name) {
public void run() {
while (true) {
System.out.println(this);
if (--countdown == 0) return;
try {
sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
public String toString() {
return getName() + ": " + countdown;
}
};
t.start();
}
}
}
public class ThreadVarations{
public static void main(String[] args) {
for(int i=0;i<10;i++)
new ThreadMethod("ThreadMethod").runTask();
}
}
The class ThreadMethod doesn't extends Thread and implements Runnable. So the class how to create a process?
You need to initiate a new Thread with a given class that implements Runnable and call start on it, the method run() would be called in the other thread.
new Thread(new ThreadMethod).start();

How to get Data from a Task in afterExecute of ScheduledThreadPoolExecutor

I'm using ScheduledThreadPoolExecutor and I don't know hot to deal with something.
I'm scheduling some tasks this way:
scheduledExecService = new ExtendedScheduledExecutor(numThreads, myThreadFactory);
TareaActualizacion act = new TareaActualizacion(inst);
ScheduledFuture<?> handle = scheduledExecService.scheduleWithFixedDelay(act, retrasoInicial, segundosRefresco, TimeUnit.SECONDS);
act is a Runnable class that recive some data by parameter:
public class TareaActualizacion implements Runnable {
private Instalacion instalacion;
public TareaActualizacion(Instalacion instalacion) {
this.instalacion = instalacion;
}
#Override
public void run() {
//Do something
}
public Instalacion getInstalacion() {
return instalacion;
}
}
Now in the afterExecute method of the ExtendedSecheduledExecutor I want to get the object Instalacion of the task TareaActualizacion but I don't know how to do it.
My ExtendedScheduledExecutor class looks like this:
public class ExtendedScheduledExecutor extends ScheduledThreadPoolExecutor{
public ExtendedScheduledExecutor(int arg0) {
super(arg0);
}
public ExtendedScheduledExecutor(int arg0, ThreadFactory arg1) {
super(arg0, arg1);
}
#Override
protected void afterExecute(Runnable r, Throwable t)
{
super.afterExecute(r, t);
System.out.println("Executing afterExecute. Throwable is " + t);
if (t != null)
t.printStackTrace();
//I need to get the Instalacion attribute from TareaActualizacion task. How can I do it??
}
}
Any idea of how can I solve it??
Thank you!
Neus
As Stephan already pointed out in https://stackoverflow.com/a/22145530 , you should try to decouple the scheduling and execution from the notification.
One approach for this could be to wrap the actual task (TareaActualizacion) into another implementation of the Runnable interface that only executes the actual task, and afterwards notifies a callback about the task that has been executed.
Depending on your precise requirements, there may be several degrees of freedom for the implementation, but a general approach could roughly look like this:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledTaskNotification
{
public static void main(String[] args) throws Exception
{
ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
int n = 3;
for (int i = 0; i < n; i++)
{
UpdateTask updateTask = new UpdateTask(i);
RunnableCallback<UpdateTask> callback = new RunnableCallback<UpdateTask>()
{
#Override
public void runnableFinished(UpdateTask updateTask)
{
System.out.println("Finished "+updateTask+", id "+updateTask.getID());
}
};
Runnable runnableWithCallback =
createRunnableWithCallback(updateTask, callback);
executor.scheduleWithFixedDelay(
runnableWithCallback, 1000, 200+i*200,
TimeUnit.MILLISECONDS);
}
}
static interface RunnableCallback<T extends Runnable>
{
void runnableFinished(T runnable);
}
private static <T extends Runnable> Runnable createRunnableWithCallback(
final T runnable, final RunnableCallback<T> callback)
{
return new Runnable()
{
#Override
public void run()
{
runnable.run();
callback.runnableFinished(runnable);
}
};
}
private static class UpdateTask implements Runnable
{
private final int id;
UpdateTask(int id)
{
this.id = id;
}
#Override
public void run()
{
System.out.println("Run "+this);
}
int getID()
{
return id;
}
#Override
public String toString()
{
return "UpdateTask "+id;
}
}
}
This is a bay way. You should not trying to get the result out of the Executor, because it is only responsible for scheduling and executing tasks, not whats happening inside of them.
Your TareaActualizacion runnable should post the result to another piece of code, where you need it. This can be achieved using a queue or in the easiest case SwingUtilities.invokeLater().

Java threads with timing implementation

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

Categories