I am using the following code as scheduler in java web deployment
public class ReportScheduler implements ServletContextListener {
private ScheduledExecutorService scheduler;
#Override
public void contextInitialized(ServletContextEvent sce) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new ReportLoader(sce.getServletContext()), 0, 10, TimeUnit.SECONDS);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
scheduler.shutdownNow();
}
The ReportLoader class which implements runnable is as follows:
public class ReportLoader implements Runnable {
ServletContext context;
public ReportLoader(ServletContext context) {
System.out.println("1");
this.context = context;
StartUp();
}
private void StartUp() {
System.out.println("start");
(new Thread(this)).start();
}
#Override
public void run() {
System.out.println("scheduled");
try {
//Files.delete(path);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
But my Scheduler does not seem to be working as nothing is getting printed on the tomcat (which is my server) log, as one would expect to.
Is there any mistake that i am making, or something more that i need to ensure so that the scheduler works properly ?
The intention of the scheduler is to delete folders at regular intervals on the local PC.
why use threadpool to run a Thread
your code:
private void StartUp() {
System.out.println("start");
(new Thread(this)).start();
}
Related
I am trying to use an EventListener to process the data produced by another component. Everything works fine the first time an event fires, but the EventListener is then removed from the list of listeners.
Here is the relevant part of the listener:
#Component
public class Listener implements ApplicationListener<CustomEvent> {
#Override
public void onApplicationEvent(CustomEvent event) {
//do stuff
}
}
And here are the publisher's relevant parts:
#Component
public class Publisher {
#Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void start() {
try {
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
CustomEvent event = new CustomEvent(this, getUpdates());
applicationEventPublisher.publishEvent(event);
}, 0, interval, TimeUnit.SECONDS);
} catch (Exception e) {
System.exit(1);
}
}
}
And the CustomEvent class:
public class CustomEvent extends ApplicationEvent {
private List<Update> updates = new ArrayList<>();
public CustomEvent (Object source, List<Update> updateList) {
super(source);
updates = updateList;
}
public List<Update> getUpdates() {
return updates;
}
}
Based on what I can tell from the debugger, it seems like the Listener bean is getting destroyed when I don't expect it to. Any idea how to keep it around to listen for events beyond the first?
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.
I am trying to execute a runnable object using the Java concurrency package's, ExecutorService SingleThreadExecutor. When I call the execute a command on the new Runnable object it simply steps over it. i.e. the run() method isn't called.
I have stepped through my lines of code using the debugger and can see my SingleThreadExecutor has been created and my Runnable is initialised.
public class RunnableDemo {
public ExecutorService executor;
public RunnableDemo () {
this.executor = Executors.newSingleThreadExecutor();
}
public void start(){
executor.execute(new MyRunnable("Hello World"));
}
public static void main(String[] args){
RunnableDemo app = new RunnableDemo();
app.start();
}
}
public class MyRunnable implements Runnable {
private String strToPrint;
public MyRunnable(String parameter) {
this.strToPrint = parameter;
}
public void run() {
System.out.println(strToPrint);
}
}
And probably self-explanatory but in this scenario, I would expect to see "Hello World" printed to screen. However, the execute/run method doesn't seem to be invoked after the runnable is created.
Your program is terminating before the executer starts the task.
You have to wait for the executor to finish like this:
public class RunnableDemo {
public ExecutorService executor;
public RunnableDemo () {
this.executor = Executors.newSingleThreadExecutor();
}
public void start(){
executor.execute(new MyRunnable("Hello World"));
}
public void awaitTermination(){
try {
service.awaitTermination(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
RunnableDemo app = new RunnableDemo();
app.start();
app.awaitTermination();
}
}
public class MyRunnable implements Runnable {
private String strToPrint;
public MyRunnable(String parameter) {
this.strToPrint = parameter;
}
public void run() {
System.out.println(strToPrint);
}
}
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();
}
}
}
I have ExecutorService at class level.
There is a rest point 'url'. So, user will call this API 'n' number of times per day.
How to shutdown the executor service if I define it class level?
CLASS LEVEL: (not sure how to shutdown executor service)
public class A {
private final ExecutorService executorService = Executors.newFixedThreadPool(3);
#GET("/url")
public void executeParallelTask() {
try {
executorService.submit(new Runnable() {
#Override
public void run() {
}
});
}
finally {
executorService.shutdown();
executorService.awaitTermination(12,TIMEUNIT.HOURS)
}
If I shutdown executor service in finally block, when next request comes at rest point, I’m getting Thread Pool size is empty and couldn’t handle the request.
I’m aware of method level like below.
public void executeParallelTask() {
executorService.submit(new Runnable() {
#Override
public void run() {
}
});
executorService.shutdown();
executorService.awaitTermination(12, TimeUnit.HOURS)
You can do it in a shutdown hook.
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
try {
if (executorService.isShutdown()) {
return;
}
log.debug("executorService shutting down...");
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
executorService.shutdownNow();
log.debug("executorService shutdown");
} catch (Throwable e) {
log.error(e, e);
}
}
});
}