I have a
ThreadPoolExecutor cachedPool = (ThreadPoolExecutor)Executors.newCachedThreadPool();
The cachededPool has to perform the following functionality in the main SimController class.
Run method for a watcher thread. Once per Second, check and call a function.
public void run(){
if(m.isChanged()){
m.toString();
}
}
But it only executes the run method once.
How can I make it run every second and create a watcher.
You can use ScheduledExecutorService.scheduleAtFixedRate() as suggested by Peter Lawrey in a comment, or you can do the following:
public void run() throws InterruptedException {
for( ;; ) {
if( m.isChanged() ) //hopefully m is thread-safe
m.toString(); //hopefully something more meaningful here
Thread.sleep( 1000 ); //1000 milliseconds is one second.
}
}
Note: if your run() method cannot throw InterruptedException, then you need to handle the InterruptedException that may be thrown by Thread.sleep(). A quick and dirty way to do this is to just say try{ ... } catch( InterruptedException e ) { throw new AssertionError( e ); } but if you want to do it the proper way, then be sure to read this: Handling InterruptedException in Java
The ScheduledExecutorService makes this pretty simple as this example, which prints the date every second, shows:
public class MonitorService {
public static void main(String[] a) throws Exception {
ScheduledExecutorService service =
Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(() -> {
System.out.println(LocalDateTime.now());
}, 0, 1, TimeUnit.SECONDS);
}
}
If you have multiple jobs to schedule in your system you would want to share the scheduled executor service among all tasks for efficiency.
If you are using Spring then you could also use #Scheduled task over a method to run a scheduled task.
#Component
#EnableScheduling
public class TestClass {
#Scheduled(fixedRate= 1000 , initialDelay = 18000)
public void TestMethod(){
// Do Something
} }
Related
I'm trying to make code that opens hourly programs made in Java. I have little knowledge of java. I tried to do similar below but it doesn't work as I want.
Code:
public static void main(String[] args) throws Exception {
for(int i = 0; i < 5; i++) {
Runtime runtime = Runtime.getRuntime();
String[] s = new String[] {"C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe"};
Process process = runtime.exec(s);
}
}
If you are looking for running this program in a scheduled manner, you can use something like
Task Scheduler in windows or Crontab in case of UNIX systems.
You need not install and run Java for that. But, if you really need it to be executed using a java code, then you can use inbuilt scheduling options in Java. One of the approach is to use a TimerTask . Added an example below
public class Task extends TimerTask {
#Override
public void run() {
try {
// I don't know, what is this app, basically you execute the logic here
Runtime runtime = Runtime.getRuntime();
String[] s = new String[] { "C:\\Program Files\\BraveSoftware\\Brave-Browser\\Application\\brave.exe" };
Process process = runtime.exec(s);
} catch (IOException e) {
// Do your thing with the errors!
e.printStackTrace();
}
}
}
And your scheduler goes like this.
public class Scheduler {
public static void main(String[] args) {
//Create a timer for scheduling
Timer schduleManager = new Timer();
//Create your task instance
Task taskInstance = new Task();
//Scheduler your task repeatedly - every one hour
schduleManager.schedule(taskInstance, 0, TimeUnit.HOURS.toMillis(1));
System.out.println(TimeUnit.HOURS.toMillis(1));
// Keep your code running - an eg.
while(true);
}
}
The program has to be exited forcefully with a Cntrl+C or console kill. There are other similar options , using different libraries as well, like
java.util.concurrent.ScheduledExecutorService
Quartz Scheduler
And more. You can explore on this.
If you are using spring boot then you can use Scheduler annotation
#Scheduled(fixedDelay = 60 * 60 * 1000
This seems to be a job requiring Java's ScheduledExecutorService. According to Java's documentation
The ScheduledExecutorService interface supplements the methods of its
parent ExecutorService with schedule, which executes a Runnable or
Callable task after a specified delay. In addition, the interface
defines scheduleAtFixedRate and scheduleWithFixedDelay, which executes
specified tasks repeatedly, at defined intervals.
Here's an example from its Javadoc that sets up a ScheduledExecutorService to beep every ten seconds for an hour:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
Here is a link to a StackOverflow answer that uses ScheduledExecutorService to run a task at a specific time.
Another alternative is to run your task as a CRON job. Here's a link to a StackOverflow answer that uses CRON to schedule a Java program.
If I understood your question correctly you can use Thread.sleep() to idle and then start the Process.
So I guess something like this would work:
public static void main(String[] args) throws InterruptedException, IOException {
ProcessBuilder pb = new ProcessBuilder("path\\to\\file.exe");
while (true) {
pb.start();
Thread.sleep(Duration.ofHours(1).toMillis());
}
}
I have a task which I scheduled to run every 30 mins. I used ScheduledExecutorService to schedule.
I want to test(junit) the exception handling for ScheduledExecutorService such that when ever there is an exception thrown, the thread is not dying because of the exception.
My code :
public enum MonitorTask {
TIMER;
private final AtomicBoolean isPublishing = new AtomicBoolean(false);
private final long period = 18000000
public synchronized boolean initialize() {
return initialize(period, period);
}
/**
* #return true, if call was successful i.e. Timer task was scheduled
*/
boolean initialize(long delay, long period) {
if (isPublishing.get()) {
log.warn("Already monitoring for new feature data");
return false;
}
//execute on daemon thread
ScheduledExecutorService scheduledExecutorService =
Executors.newSingleThreadScheduledExecutor(runnable -> {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
return thread;
}
);
Runnable runnableTask = () -> {
try {
DataPublisher.INSTANCE.update(DateTime.now());
} catch (Throwable e) {
log.warn("Failed to check for new Data!", e);
}
};
scheduledExecutorService.scheduleAtFixedRate(runnableTask, delay, period, TimeUnit.MILLISECONDS);
isPublishing.set(true);
return true;
}
}
As for now, my unit test check for the functionality:
public class MonitorTaskTest {
#Test
public void testInitialize() throws Exception {
AtomicInteger val = new AtomicInteger(0);
DataProvider provider = testProvider(val);
assertEquals(0, val.get());
// this should update val every 10 ms ( adds 1 to val )
Assert.assertTrue(MonitorTask.TIMER.initialize(0, 10));
assertEquals(0, val.get());
DataPublisher.INSTANCE.registerForNewData(provider, DateTime.now());
// wait for 3 updates
Thread.sleep(10 * 3);
Assert.assertTrue("Expected val to be >= 3 but is " + val.get(), val.get() >= 3);
}
#Before
public void setUp() {
DataPublisher.INSTANCE.clear();
}
private static DataProvider testProvider(final AtomicInteger ai) {
return new DataProvider() {
private AtomicInteger val = ai;
#Override public boolean update(DateTime dateTime) throws Exception {
val.incrementAndGet();
return true;
}
#Override public boolean exists(DateTime dateTime) {
return true;
}
#Override public void close() throws Exception {
}
};
}
}
I think you are going down the wrong rabbit hole here. Meaning: when you check the javadoc for the method you are using, you find:
Creates a single-threaded executor that can schedule commands to run after a given delay, or to execute periodically. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
In other words: you are asking how to test something that is guaranteed to work by the Java system library you are using. And in that sense you are wasting your time.
You might rather spend time to improve your code to make it easier to test. You see - when your class would receive an ExecutorService object (instead of creating one for itself) you could pass in a same thread executor for your unit tests. And all of a sudden, your unit tests can run on one thread which makes the whole testing a lot easier - as it allows you to get rid of your sleep statements in your tests. (and those sleep statements are much more of a problem than chances that threads are not re-started although the system library guarantees you to do so).
Beyond that: your runnable is already written in a way that should guarantee that threads running this code never die (of course, it is questionable to catch Throwable). But in order to test that, I guess you only need another "test provider" where update() throws any kind of exception.
I am writing code in java and I am making a request from another system. I want that if I won't get a response while I am counting (parallel), I will call send error function or throw exception to be catched in the main thread
try {
StartTimer();
result = request.ExecuteOperation();
sendSuccess(result);
}
catch (MyExeption ex) {
handleExeption(ex!= null? ex.getMessage(): "General Exeption", ex, systemID)
}
How does StartTimer() count 2 minutes and check if ExecuteOperation() returned and if 2 minutes have passed to throw MyException that will be caught in the main thread?
First of all, many blocking API calls have a timeout parameter that you may be able to use.
If not, I would turn this around and do the executeOperation bit on a background thread, wrapped in a Future.
The current thread can then call get on the Future with a timeout specified.
Future<MyResult> futureResult = executor.submit(new Callable<MyResult>(){
void call(){
return request.ExecuteOperation();
}
});
return futureResult.get(2, TimeUnit.MINUTES);
You could use a CountDownLatch, https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html#await(long,%20java.util.concurrent.TimeUnit). Something like:
public class Test {
public void executeOperation(CountDownLatch latch ) {
// runs on separate thread and perform the operation
latch.countDown();
}
public static void main(String[] args) throws Exception {
Test test = new Test();
CountDownLatch latch = new CountDownLatch(1);
test.executeOperation(latch);
if (!latch.await(2, MINUTES)) {
// report an error
}
}
}
I am working on writing some junit test for my spring application. Below is my junit test that that calls afterPropertiesSet method of my InitializeFramework class that implements InitializingBean interface.
Below is the flow where my junit test calls afterPropertiesSet method and then that method will call initializeModel method within the same class, and then that method has a scheduler which will call getBundlesInfo method every few minutes. But somehow during my junit, getBundlesInfo method is not getting called at all.
#Test
public void testFramework() {
try {
InitializeFramework io = new InitializeFramework();
io.afterPropertiesSet();
} catch (Exception e) {
}
}
public class InitializeFramework implements InitializingBean {
private static long checkWithDBInterval = 1L;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
#Override
public void afterPropertiesSet() throws Exception {
try {
// other code here
initializeModel();
} catch (Exception e) {
}
}
private void initializeModel() {
final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(
new Runnable() {
public void run() {
try {
getBundlesInfo();
} catch(Exception ex) {
// log exception here
}
}
}, 0, checkWithDBInterval, TimeUnit.MINUTES);
}
// this method is not getting called from my junit test
protected static void getBundlesInfo() {
// some code here
// have put the breakpoint here..
}
}
Can anybody help me with this? What wrong I am doing here? but during my application run, this flow works perfectly fine and getBundlesInfo gets called... Only during junit it is not working..
This happens because your unit test exits before the scheduler executes your Runnable.
Do you want to test that afterPropertiesSet calls getBundlesInfo or do you want to test the repeated invocation of getBundlesInfo?
How does your unit test assert that getBundlesInfo got called? Or are you not there yet?
If you just want to see that getBundlesInfo is called, you either could make a direct call to it and increase the initialDelay of your scheduler to checkWithDBInterval, or stub getBundlesInfo with Mockito and/or Powermock to for example use a CountDownLatch to synchronize on.
Well or just wait a couple of seconds after the call to afterPropertiesSet and then check if getBundlesInfo was called (which you can do with Mockito also btw).
In any case, you might want to add code which calls shutdown on the executor service after the test is finished
Since you use Spring:
Consider using the provided Task Execution and Scheduling framework to schedule the repeated call to getBundlesInfo and having afterPropertiesSet directly call getBundlesInfo initially.
Anyway, here is an example with stubbing and using a CountDownLatch for the waiting part.
I also had to make getBundlesInfo non-static, as i couldnt quickly remember/find how to stub a static method.
import static org.mockito.Mockito.*;
import java.util.concurrent.*;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class StackOverflowTest
{
public static class ClassWithScheduler
{
private static long checkWithDBInterval = 1L;
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool( 1 );
public void entryPoint()
{
scheduler.scheduleAtFixedRate( new Runnable() {
public void run()
{
try
{
thisHasToBeCalled();
}
catch( Exception ex )
{
// log exception here
}
}
}, 0, checkWithDBInterval, TimeUnit.MINUTES );
}
protected void thisHasToBeCalled()
{
System.out.println( "thisHasToBeCalled was called" );
}
}
// since we are waiting on another thread either use a timed-wait (latch.await also
// has a variant which accepts a timeout) or use the timeout attribute of the
// #Test annotation
#Test( timeout = 5000L )
public void testCall() throws Exception
{
// create latch which this thread waits on and the scheduler thread
// notifies on
final CountDownLatch latch = new CountDownLatch( 1 );
// create instance
ClassWithScheduler instance = spy( new ClassWithScheduler() );
// stub thisHasToBeCalled to notify on the latch
doAnswer( new Answer<Void>() {
#Override
public Void answer( InvocationOnMock invocation ) throws Throwable
{
// call the real method
invocation.callRealMethod();
// notify waiting thread
latch.countDown();
System.out.println( "stub" );
return null;
}
} ).when( instance ).thisHasToBeCalled();
// execute
instance.entryPoint();
// wait for thread to call the stubbed method
latch.await();
// assert that the method was called /
verify( instance ).thisHasToBeCalled();
}
}
You will notice that if you change your getBundlesInfo() to something like
protected static void getBundlesInfo() {
System.out.println("ay");
}
and the TimeUnit you are using to TimeUnit.MILLISECONDS, that it will print as much as it can. For example, I got
ay
ay
ay
ay
This is because JUnit cleans up any threads running on the JVM before exiting. It kills/stops/interrupts them.
I have the following problem that the standard library doesn't solve well, and I'm wondering if anybody has seen another library out there than can do it so I don't need to hack together a custom solution. I have a task that is currently scheduled on a thread pool using scheduleWithFixedDelay(), and I need to modify the code to handle requests for "urgent" execution of the task related to asynchronous events. Thus, if the task is scheduled to occur with a delay of 5 minutes between executions, and an event occurs 2 minutes after the last completed execution, I would like to execute the task immediately and then have it wait for 5 minutes after the completion of the urgent execution before it runs again. Right now the best solution that I can come up with is to have the event handler call cancel() on the ScheduledFuture object returned by scheduleWithFixedDelay() and execute the task immediately, and then set a flag in the task to tell it to reschedule itself with the same delay parameters. Is this functionality available already and I'm just missing something in the documentation?
If you are using ScheduledThreadPoolExecutor there is a method decorateTask (well in fact there are two, for Runnable and Callable tasks) that you can override to store a reference to the task somewhere.
When you need urgent execution, you just call run() on that reference which makes it run and rescheduled with same delay.
A quick hack-up attempt:
public class UrgentScheduledThreadPoolExecutor extends
ScheduledThreadPoolExecutor {
RunnableScheduledFuture scheduledTask;
public UrgentScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize);
}
#Override
protected RunnableScheduledFuture decorateTask(Runnable runnable,
RunnableScheduledFuture task) {
scheduledTask = task;
return super.decorateTask(runnable, task);
}
public void runUrgently() {
this.scheduledTask.run();
}
}
which can be used like this:
public class UrgentExecutionTest {
public static void main(String[] args) throws Exception {
UrgentScheduledThreadPoolExecutor pool = new UrgentScheduledThreadPoolExecutor(5);
pool.scheduleWithFixedDelay(new Runnable() {
SimpleDateFormat format = new SimpleDateFormat("ss");
#Override
public void run() {
System.out.println(format.format(new Date()));
}
}, 0, 2L, TimeUnit.SECONDS);
Thread.sleep(7000);
pool.runUrgently();
pool.awaitTermination(600, TimeUnit.SECONDS);
}
}
and produces the following output:
06
08
10
11
13
15
as requested (soz, in a hurry) my EventBasedExecutor
Warning: This currently only works for tasks that are scheduled in a periodic run. You can change the code to handle all the tasks, I so far haven't because I only have the periodically run task. I also run this in a signle-threaded threadpool (I only need one scheduled runner thread that is that runs in one dedicated thread all the time every X seconds)
Here we go:
public class EventBasedExecutor extends ScheduledThreadPoolExecutor implements EventBasedExecutorService {
private List<RunnableScheduledFuture<?>> workers = new ArrayList<>();
private int index;
public EventBasedExecutor(int corePoolSize) {
super(corePoolSize, new ThreadFactoryBuilder().setDaemon(true).setNameFormat("message-sender-%d").build());
}
#Override
protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) {
if(!workers.contains(runnable)) {
workers.add(task);
}
return super.decorateTask(runnable, task);
}
#Override
public void executeEarly() {
if(index >= workers.size()) {
index = 0;
}
if(workers.size() == 0) {
return;
}
RunnableScheduledFuture<?> runnableScheduledFuture = workers.get(index);
index ++;
execute(runnableScheduledFuture);
System.out.println("Executing");
}
public static void main(String[] args) throws InterruptedException {
EventBasedExecutor executor = new EventBasedExecutor(10);
long currentTimeMillis = System.currentTimeMillis();
// this will never run
executor.scheduleAtFixedRate(() -> {
System.out.println("hello");
}, 5000, 5000, TimeUnit.HOURS);
executor.executeEarly();
System.out.println("Run after: " + (System.currentTimeMillis() - currentTimeMillis));
}
}
This will execute the task in the dedicated worker thread.
It will print:
Executing
hello
Run after: 39
Have fun hacking :)
artur
There is also an obvious simple solution that does not require a new class.
The idea is to cancel the schedule on notification and re-schedule again:
class MyClass {
final static int DECISION_POINT = 1; //millisecond
final ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
private ScheduledFuture<?> periodicFuture;
MyClass() {
periodicFuture = executor.scheduleWithFixedDelay(this::doWork, 1, 2,
TimeUnit.SECONDS);
}
void doWorkAsap() {
if (periodicFuture.getDelay(TimeUnit.MILLISECONDS) > DECISION_POINT) {
periodicFuture.cancel(true);
periodicFuture = executor.scheduleWithFixedDelay(this::doWork,
0, 2000, TimeUnit.MILLISECONDS);
}
}
void doWork() { ... }
}
This only works well in certain situations where delay between tasks is reasonably big relative to overall system performance and overhead of creating new ScheduledFuture is acceptable. Also, special attention needs to be paid to the point of no return, called DECISION_POINT here, where it makes no more sense to schedule the new future, as natural order of things would be fast enough. For the tighter schedules than in the example above, use an approach similar to the pandaab one.