I'm looking to create a ScheduledThreadPoolExecutor with an unknown pool size. Pool size is determined at run-time, will likely be between 1-5, and for this example I used size 2. We use a custom Task that simply executes a method every so often, but that method will eventually throw an exception (which I've simulated with a simple numTimes variable and if statement). If an exception is thrown, I only want to cancel execution of THAT specific thread! If all threads are cancelled, I want to shut down the ScheduledThreadPoolExecutor. Once numTimes == 5 I simulate the exception to cancel the thread), and I can manage to cancel the thread a number of ways but they just don't feel right.
As a side note, I placed ScheduledFuture everywhere just to play around with cancelling it.
public class Test
{
static ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
public static void main(String[] args)
{ stpe.scheduleWithFixedDelay(new UpdateTask(1), 0, 1000, TimeUnit.MILLISECONDS);
stpe.scheduleWithFixedDelay(new UpdateTask(2), 0, 5000, TimeUnit.MILLISECONDS);
// stpe.shutdown();
}
public static class UpdateTask implements Runnable
{
int id;
int numTimes = 0;
ScheduledFuture<?> t;
public UpdateTask(int id)
{ this.id = id;
}
public void run()
{ System.out.println("Hello " + id + " num: " + numTimes);
String fn = "C:\\lib" + id;
if (numTimes++ == 5)
{ File f = new File(fn);
f.mkdir();
t.cancel(false);
}
}
}
}
Calling t.cancel() from run() or from main() have the same effect, in that the thread stops executing but the program does not stop running. Naturally, this is because the ThreadPoolExecutor is still doing stuff, despite both threads no longer being scheduled.
I tried invoking shutdown on stpe, but it doesn't finish thread execution. Two directories are created with stpe.shutdown commented out, and they are not otherwise.
I can't figure out an elegant way to cancel ScheduledFuture, then ScheduledThreadPoolExecutor when all ScheduledFuture's are cancelled.
Final approach ##
I was not able to get s1.get() to work as described in the answer below, so I simply created my own class to handle it.
public class Test
{
static ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(2);
static CancelUpdateTasks canceller;
public static void main(String[] args)
{ Test t = new Test();
canceller.add(0, stpe.scheduleWithFixedDelay(new UpdateTask(0), 0, 1000, TimeUnit.MILLISECONDS));
canceller.add(1, stpe.scheduleWithFixedDelay(new UpdateTask(1), 0, 5000, TimeUnit.MILLISECONDS));
canceller.waitForSchedules();
stpe.shutdown();
}
public Test()
{ canceller = new CancelUpdateTasks();
}
public static class UpdateTask implements Runnable
{
int id;
int numTimes = 0;
public UpdateTask(int id)
{ this.id = id;
}
public void run()
{ System.out.println("Hello " + id + " num: " + numTimes);
if (numTimes++ == 5)
{ canceller.cancel(id);
}
}
}
public class CancelUpdateTasks
{ List<ScheduledFuture<?>> scheduler;
boolean isScheduled;
public CancelUpdateTasks()
{ scheduler = new ArrayList<ScheduledFuture<?>>();
isScheduled = false;
}
public void waitForSchedules()
{ int schedId = 0;
while(isScheduled)
{ ScheduledFuture<?> schedule = scheduler.get(schedId);
if (schedule.isCancelled())
{ if (schedId == scheduler.size() - 1)
return;
schedId++;
}
else
{ try
{ Thread.sleep(1000);
}
catch (InterruptedException e)
{ e.printStackTrace();
}
}
}
}
public void add(int id, ScheduledFuture<?> schedule)
{ scheduler.add(id, schedule);
if (!isScheduled)
isScheduled = true;
}
public void cancel(int id)
{ scheduler.get(id).cancel(false);
}
public void cancelNow(int id)
{ scheduler.get(id).cancel(true);
}
}
}
You'll want to issue a shutdown on the pool. The JVM will continue to run until there are only daemon threads alive. A ThreadPoolExecutor by default will create non-daemon threads.
Just invoke stpe.shutdown();
edit: Based on OPs update
shutdown admittedly is different for ScheduledThreadPoolExecugtor than a plain ThreadPoolExecutor. In this case shutdown prevents any scheduled task to become re scheduled. To make it work correctly you will have to wait on the futures completion. You can do so by get()ing on the ScheduledFuture
ScheduledFuture sf1 = stpe.scheduleWithFixedDelay(new UpdateTask(1), 0, 1000, TimeUnit.MILLISECONDS);
ScheduledFuture sf2 = stpe.scheduleWithFixedDelay(new UpdateTask(2), 0, 5000, TimeUnit.MILLISECONDS);
sf1.get();
sf2.get();
stpe.shutdown();
In this case both tasks are run asynchronously, the main thread will first wait for sf1 to complete then will wait for sf2 to complete and finally shutdown.
Related
I'm using a task that creates other tasks. Those tasks in turn may or may not create subsequent tasks. I don't know beforehand how many tasks will be created in total. At some point, no more tasks will be created, and all the task will finish.
When the last task is done, I must do some extra stuff.
Which threading mechanism should be used? I've read about CountDownLatch, Cyclic Barrier and Phaser but none seem to fit.
I've also tried using ExecutorService, but I've encountered some issues such as the inability to execute something at the end, and you can see my attempt below:
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class Issue {
public static void main(String[] args) throws InterruptedException {
var count = new AtomicInteger(1);
var executor = Executors.newFixedThreadPool(3);
class Task implements Runnable {
final int id = count.getAndIncrement();
#Override
public void run() {
try {
MILLISECONDS.sleep((long)(Math.random() * 1000L + 1000L));
} catch (InterruptedException e) {
// Do nothing
}
if (id < 5) {
executor.submit(new Task());
executor.submit(new Task());
}
System.out.println(id);
}
}
executor.execute(new Task());
executor.shutdown();
// executor.awaitTermination(20, TimeUnit.SECONDS);
System.out.println("Hello");
}
}
This outputs an exception because tasks are added after shutdown() is called, but the expected output would be akin to:
1
2
3
4
5
6
7
8
9
Hello
Which threading mechanism can help me do that?
It seems pretty tricky. If there is even a single task that's either in the queue or currently executing, then since you can't say whether or not it will spawn another task, you have no way to know how long it may run for. It may be the start of a chain of tasks that takes another 2 hours.
I think all the information you'd need to achieve this is encapsulated by the executor implementations. You need to know what's running and what's in the queue.
I think you're unfortunately looking at having to write your own executor. It needn't be complicated and it doesn't have to conform to the JDK's interfaces if you don't want it to. Just something that maintains a thread pool and a queue of tasks. Add the ability to attach listeners to the executor. When the queue is empty and there are no actively executing tasks then you can notify the listeners.
Here's a quick code sketch.
class MyExecutor
{
private final AtomicLong taskId = new AtomicLong();
private final Map<Long, Runnable> idToQueuedTask = new ConcurrentHashMap<>();
private final AtomicLong runningTasks = new AtomicLong();
private final ExecutorService delegate = Executors.newFixedThreadPool(3);
public void submit(Runnable task) {
long id = taskId.incrementAndGet();
final Runnable wrapped = () -> {
taskStarted(id);
try {
task.run();
}
finally {
taskEnded();
}
};
idToQueuedTask.put(id, wrapped);
delegate.submit(wrapped);
}
private void taskStarted(long id) {
idToQueuedTask.remove(id);
runningTasks.incrementAndGet();
}
private void taskEnded() {
final long numRunning = runningTasks.decrementAndGet();
if (numRunning == 0 && idToQueuedTask.isEmpty()) {
System.out.println("Done, time to notify listeners");
}
}
public static void main(String[] args) {
MyExecutor executor = new MyExecutor();
executor.submit(() -> {
System.out.println("Parent task");
try {
Thread.sleep(1000);
}
catch (Exception e) {}
executor.submit(() -> {
System.out.println("Child task");
});
});
}
}
If you change your ExecutorService to this:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
You could then use the count functions to wait:
while(executor.getTaskCount() > executor.getCompletedTaskCount())
{
TimeUnit.SECONDS.sleep(10L);
}
executor.shutdown();
System.out.println("Hello");
I have a simple java program I use to generate elements and insert them in DB every X seconds during a specific time.
The generation is done with a scheduleAtFixedRate. there is only one of these.
I want my program to quit completely when the scheduled task is over. To do so, I use System.exit() when the task is canceled, but is it the correct way to do this ?
Here is my current code:
public static void main(String[] args) throws InterruptedException {
c = generateDbConnection(url, user, password);
if (c != null) {
s = generateDbStatement(c);
} else {
System.out.println("ERROR");
return;
}
initialTimestamp = new Date();
TimeUnit.SECONDS.sleep(1);
generateForAnHour();
}
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
/**
* Generator thread handler Uses Statement from main function
*/
public static void generateForAnHour() {
final Runnable runner = new Runnable() {
public void run() {
String[][] data = new String[numberOfIds][2];
for (int i = 0; i < numberOfIds; i++) {
data[i] = generateDevice();
insertDevice(s, data[i][0], data[i][1]);
}
quantityOfIds += numberOfIds;
}
};
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 5, TimeUnit.SECONDS);
scheduler.schedule(new Runnable() {
public void run() {
generatorHandle.cancel(true);
System.out.println("Scheduled ID generator terminated.");
System.exit(0); //TODO Is it really correct way to do it
}
}, timeToRun, TimeUnit.SECONDS);
}
I am not sure if this is the correct way to stop the execution of your program if it has some more functions, but I, personally, find it an OK way. :D
So, as it turned out, ScheduledExecutorService seemingly creates non-daemon threads with its default ThreadFactory, perhaps we need to supply a daemonic one to it.
However, if we are to call ExecutorService#shutdown or the forceful ExecutorService#shutdownNow, it will stop both tasks from executing, thus removing the thread(s) that prevent the application from ending its job:
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
public static void main(String[] args) {
// Some service code here
generateForAnHour();
}
public static void generateForAnHour() {
// Some code that does work
final Runnable runner = () -> System.out.println("Running...");
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 1, TimeUnit.SECONDS);
// Code that interrupts the worker after a specified time
scheduler.schedule(scheduler::shutdown, 5, TimeUnit.SECONDS);
}
Output:
Running...
Running...
Running...
Running...
Running...
Running...
Process finished with exit code 0
I hope this will help. :D
This answer is secondary to this one, but it has a different way to solve the problem, so I thought it is appropriate enough to create a separate answer.
If you want to have some more tasks in the future, I believe this solution is more scalable and is more "correct thing".
It creates daemon threads for both runner and interrupter. I think it would be better to create a normal thread factory for the interrupter, but I failed to make it working, so it's better to stick to my first answer...
Here generateForAnHour returns a Future that is used to wait for the time needed.
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1 , new ThreadFactory() {
#Override
public Thread newThread(final Runnable r) {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}
});
public static void main(String[] args) throws InterruptedException, ExecutionException {
// Some service code here
generateForAnHour().get();
}
public static ScheduledFuture<Boolean> generateForAnHour() {
// Some code that does work
final Runnable runner = () -> System.out.println("Running...");
final ScheduledFuture<?> generatorHandle = scheduler.scheduleAtFixedRate(runner, 0, 1, TimeUnit.SECONDS);
// Code that interrupts the worker after a specified time
return scheduler.schedule(() -> generatorHandle.cancel(false), 5, TimeUnit.SECONDS);
}
If you won't call Future#get, you'll receive only one Running... in best case or none at all.
If you decide to return the runner future, you'll probably get nasty CancellationException in the get() call:
Exception in thread "main" java.util.concurrent.CancellationException
at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:121)
at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
at com.xobotun.Test.main(Test.java:30)
I'd use the ExecutorService::shutdown approach as the stabler and more understandable one. :D
I have to process a lot of files. I wrote simple Java program that does the job, but it is too slow.
I need more than 1 working thread.
Im totally new with Java and Java multithreading.
Here is my code (simplified):
public static void main(String[] args)
{
// some queue here?
for (int i = 1; i < 8000000; i++)
{
processId(i);
}
}
public static void processId(int id)
{
try
{
// do work
System.out.println("Im working on: " + Integer.toString(id));
}
catch (Exception e)
{
// do something with errors
System.out.println("Error while working on: " + Integer.toString(id));
}
}
How can I add simple queue with 8 threads?
You should look into Executors.
You can create a thread pool of 8 threads using:
ExecutorService executor = Executors.newFixedThreadPool(8);
Then submit your tasks inside your loop the following way:
final int finalId = i; // final is necessary to be enclosed in lambda
executor.submit(() -> processId(finalId));
Or prior to java 8:
final int temp = i; // final is necessary to be enclosed in anonymous class
executor.submit(new Runnable() {
public void run() {
processId(finalId);
}
});
Don't forget to shutdown the thread pool when not needed anymore, as mentioned in the documentation. Here is an example from the doc:
private void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
You should look into ExecutorService. This will make multithreading easy. An example:
Main code:
ExecutorService pool = Executors.newFixedThreadPool(8);
for (int i = 1; i < 8000000; i++) {
pool.submit(new intProcessingTask(i));
}
pool.shutdown();
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
// all tasks have now finished (unless an exception is thrown above)
intProcessingTask code:
private static class DownloadTask implements Runnable {
private int id;
public DownloadTask(int id) {
this.id = id;
}
#Override
public void run() {
System.out.println("Im working on: " + Integer.toString(id));
}
}
This is slightly longer than the the other answer, but does pretty much the same thing, and works on Java 7 and earlier.
There are many ways in Java for processing mulithreading. Base on your question that you need a queue, I think the most simple version is use Java ExecutorService. You can see this code:
public static void main(String[] args) {
// creating a thread pool with maximum thread will be 8
ExecutorService executorService = Executors.newFixedThreadPool(8);
for (int i = 0; i < 8000000; i++) {
final int threadId = i;
executorService.execute(new Runnable() {
public void run() {
processId(threadId);
}
});
}
}
ExecutorService has some methods:
execute(Runnable)
submit(Runnable)
submit(Callable)
invokeAny(...)
invokeAll(...)
I recommend you view this link: ExecutorService tutorial for clear explanation.
Hope this help :)
I was handled a design of a threaded application that has the following requirement: It has to have a dynamic number of threads it runs based on the time of day (Peak/off-peak).
I did my homework and researched for the best way to do this, and I found that java has a class named ThreadPoolExecutor:
java.util.concurrent.ThreadPoolExecutor.ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
The two variables in focus here are the corePoolSize, and the maximumPoolSize, both act as the lower and the upper bound of the thread pool along with the workQueue. tuning these values have different strategies and it is advisable to use the executer factory methods instead of the constructor in case these parameters are not needed to be set explicitly.
public class Main {
public static void main(String[] args) {
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(0, 10, 0L, TimeUnit.MILLISECONDS, queue);
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
TimerTask task = new TimerTask() {
#Override
public void run() {
threadPool.setCorePoolSize(1);
threadPool.setMaximumPoolSize(1);
System.out.println("changed");
}
};
new Timer().schedule(task, 10000);
for (int i = 0; i < 400; i++) {
threadPool.submit(new WorkItem(i));
}
}
}
And this is the class that resembles the thread to run
public class WorkItem implements Runnable {
private int workItemNumber;
private long startTime;
public WorkItem(int workItemNumber) {
this.workItemNumber = workItemNumber;
}
#Override
public void run() {
startTime = System.currentTimeMillis();
System.out.println("thread Number: " + workItemNumber + " started at: " + startTime);
while (System.currentTimeMillis() - startTime < 5000) {
}
System.out.println("WorkItem done: " + workItemNumber);
}
}
However, looking at the logs, the number of executed threads remain the same with no change.
Your code is running exactly as you intend it to. 10 threads are started and run, and 100 threads are queued. At that point, your main thread (the one queuing threads) is blocked by the blocking queue. Your timer then changes the available threads to 1, meaning your queue processes even slower. What you are seeing however, is that because your threads have to wait for longer than 10 seconds to actually execute they complete immediately. Try making the following changes to your code:
public class WorkItem implements Runnable {
private long startTime;
private long runTime;
private int workItemNumber;
public WorkItem(long startTime, int workItemNumber) {
this.startTime = startTime;
this.workItemNumber= workItemNumber;
}
#Override
public void run() {
System.out.println("WorkItem started: " + workItemNumber + " Queued at: " + startTime);
runTime = System.currentTimeMillis();
while (System.currentTimeMillis() - runTime < 10000) {
}
System.out.println("WorkItem done: " + workItemNumber);
}
}
This will let you see the execution occurring as you would expect. The strange thing about using an array blocking queue with your core pool set to 0 is that it'll only start a single thread, then fill up the queue, then start more threads (up to max pool size). You can see this happening if you make a subtle change to your queuing code.
for (int i = 1; i < 101; i++) {
threadPool.submit(new WorkItem(System.currentTimeMillis(), i));
}
for (int i = 101; i < 401; i++) {
long thisTime = System.currentTimeMillis();
threadPool.submit(new WorkItem(System.currentTimeMillis(), i));
while (System.currentTimeMillis() - thisTime < 500) {
}
}
You've created a pool with 10 max threads
new ThreadPoolExecutor(0, 10, 0L, TimeUnit.MILLISECONDS, queue);
and you've submitted 400 tasks
for (int i = 0; i < 400; i++) {
threadPool.submit(new Thread(System.currentTimeMillis(), i));
}
The thread pool will not use more than 10 threads (threads represented by the java.lang.Thread class) to execute your tasks.
Submitting and executing all these tasks takes less than the 10000 millisecond delay you've set for your TimerTask
new Timer().schedule(task, 10000, 5000);
Once your TimerTask is run, your pool will only have one thread running and claiming submitted tasks (once the other threads' tasks are completed).
Sample that will show that only one thread will remain in the ThreadPoolExecutor once the TimerTask has been executed (and after any executing tasks finish)
public class Jackson {
public static void main(String[] args) {
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(100);
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(0, 10, 0L, TimeUnit.MILLISECONDS, queue);
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
TimerTask task = new TimerTask() {
#Override
public void run() {
threadPool.setCorePoolSize(1);
threadPool.setMaximumPoolSize(1);
System.out.println("changed");
this.cancel();
}
};
new Timer().schedule(task, 5, 5000);
for (int i = 0; i < 400; i++) {
threadPool.submit(new WorkItem(i));
}
}
}
class WorkItem implements Runnable {
private int workItemNumber;
public WorkItem(int workItemNumber) {
this.workItemNumber = workItemNumber;
}
#Override
public void run() {
System.out.println("WorkItem #" + workItemNumber + " executing on Thread with name: " + Thread.currentThread().getName());
}
}
Whilst using this on later version of JDK/Grails setting max poolSize reducing it all works well in older versions of grails and JDK7. (Unsure where the problem resides I had to do this)
private static final int actualPoolSize = Holders.grailsApplication.config.maximumPoolSize ?: 3
private static int maxPoolSize = actualPoolSize
public EnhancedExecutor() {
super(maxPoolSize,maxPoolSize,keepAliveTime,timeoutUnit,new PriorityBlockingQueue<Runnable>(maxQueue))
}
public void setMaxPoolSize(int i) {
this.maxPoolSize=i
super.purge()
super.setCorePoolSize(i?:actualPoolSize)
super.setMaximumPoolSize(i?:actualPoolSize)
}
Without the purge I could increase to a higher level without any errors. Attempting to reduce returned a null for i . or actualPoolSize. (did not seem to want to shrink without throwing an exception).
I took on comments from BretC about threads being busy and it appears purge solves that by ensuring all is reset before attempting to reset superValues
It looks like the "Set maximum pool size" method will reduce the number of idle threads only...
public void setMaximumPoolSize(int maximumPoolSize) {
if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
throw new IllegalArgumentException();
this.maximumPoolSize = maximumPoolSize;
if (workerCountOf(ctl.get()) > maximumPoolSize)
interruptIdleWorkers();
}
If threads stay busy, it doesn't look like they are released.
(I could be wrong... It doesn't look like anything magical happens when a thread is finished to clean things up - need to take more of a look...)
How would I have this method run every couple of seconds in a recursive function.
I want the i variable to update by 1 every couple of seconds than print it to the console.
In javascript I could use setTimeout is there a method like the javascript setTimeout in Java?
final i = 0;
public void timerActions() {
i = i + 1;
System.out.println(i);
}
try with Timer
Timer timer = new Timer("Display Timer");
TimerTask task = new TimerTask() {
#Override
public void run() {
timerActions();
}
};
// This will invoke the timer every second
timer.scheduleAtFixedRate(task, 1000, 1000);
}
You should use ScheduledExecutorService for that.
Update per Peter Lawrey comment (thanks):
Methods :
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
long initialDelay,
long period,
TimeUnit unit);
and
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit);
can be used in order to achieve your desired behavior.
You can put the Thread to sleep after execution if it's just a simple application which just has to "run slower".
For example:
final i = 0;
public void timerActions() {
i++;
System.out.println(i);
Thread.sleep(1000);
}
1000 in the parentheses means 1000ms=1second - the amount of time in which the thread sleeps.
This is a simple way to do it, but be aware that in larger multi-threaded applications you have to take into acount thread safety and related problems.
Documentation for Thread.sleep()
public class TimedAction
{
public static void main(String[] args) throws Exception
{
System.out.println("begin");
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable command = new Runnable()
{
private int i = 0;
#Override
public void run()
{
// put your logic HERE
System.out.println(i++);
}
};
// execute command, immediately (0 delay), and every 2 seconds
executor.scheduleAtFixedRate(command, 0, 2, TimeUnit.SECONDS);
System.in.read();
executor.shutdownNow();
executor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("end");
}
}
This will print "Counting..." on every 2 seconds
import java.util.Timer;
import java.util.TimerTask;
public class MyTimerTask extends TimerTask {
private int counter = 0;
public void run() {
counter++;
if (counter <= 3) {
System.out.println("Counting - counter = " + counter);
} else {
System.out.println("Stopping timer execution");
this.cancel();
}
}
public static void main(String[] args) {
Timer timer = new Timer("TimerThreadName");
MyTimerTask task = new MyTimerTask();
// void java.util.Timer.schedule(TimerTask task, long delay, long period)
timer.schedule(task, 0, 2000);
}
}