1

I have been tasked with creating a Java version of a C# SDK. Currently. I am working on a class that extends the C# System.ServiceProcess.ServiceBase but due to the difficulty of creating Windows services in Java I am focusing on some of the other methods in the class.

The current C# method I am attempting to replicate in Java looks as follows

    private void StartProcesses()
    {
        // create a new cancellationtoken souce
        _cts = new CancellationTokenSource();

        // start the window timer
        _windowTimer = new Timer(new TimerCallback(WindowCallback),
            _cts.Token, 0, Convert.ToInt64(this.SQSWindow.TotalMilliseconds));

        this.IsWindowing = true;
    }

After analyzing this section of code I believe that it initializes a System.threading.Timer object that executes the WindowCallback function every SQSWindow milliseconds.

After reading through the java.util.concurrent documentation located

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html

I am unsure how I would replicate the C# functionality in Java as I cannot find the equivalent to the Timer functionality. The TimeUnit provided by the Java library appears to be only used for thread timeouts and not to issue recurring operations.

I am also curious as to the use of the CancellationTokenSource. If this object is meant to be queried to determine if the action is to continue, why is it not a primative such as a boolean? What additional functionality does it provide, and is there a similar construct in Java's multithreading model?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
JME
  • 2,293
  • 9
  • 36
  • 56

3 Answers3

2

Using a ScheduledThreadPoolExecutor, you can get very similar functionality:

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
Runnable task = new Runnable() {
    public void run() {
        //here the code that needs to run periodically
    }
};
//run the task every 200 ms from now
Future<?> future = scheduler.scheduleAtFixedRate(task, 0, 200, TimeUnit.MILLISECONDS);
//a bit later, you want to cancel the scheduled task:
future.cancel(true);
assylias
  • 321,522
  • 82
  • 660
  • 783
  • I'm going to go ahead and upvote yours as the executors seem the way to go after reading about them. – greedybuddha Jun 07 '13 at 19:44
  • @greedybuddha Thanks! There are indeed [very few reasons to prefer Timer over ScheduledExecutorService](http://stackoverflow.com/questions/2213109/java-util-timer-is-it-deprecated) (one of them being when you want to schedule something to run at a specific time: Timer allows you to give a Date, whereas with SES you need to calculate the duration). – assylias Jun 07 '13 at 19:47
  • The WindowCallback method polls and parses messages from an AmazonSQS service. As such, there are cases where if more than a certain number of messages are received it creates multiple threads to handle the parsing. Will I need to worry about this if I use your example that uses a SingleThreadScheduledExecutor or will it resolve itself? – JME Jun 07 '13 at 19:49
  • @JME These threads need to be managed by the task itself (the WindowCallback method in your case). The only reason to increase the number of threads in the SES is if you think that two consecutive runs might overlap. Imagine you run the task every 200ms but each task takes 800ms. You should use at least 4 threads to make sure that the currently running tasks don't delay the next ones. In that case, use `ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);` for 4 threads, for example. – assylias Jun 07 '13 at 19:53
  • And there is little cost to adding a few threads, so using double what you probably need (i.e. 8 threads in my previous example) is not an issue. – assylias Jun 07 '13 at 19:54
1

The equivalent Java classes are `Timer and TimerTask.

Example:

Timer t = new Timer();
t.schedule(new TimerTask(){

    @Override
    public void run() {
        // Do stuff
    }

}, startTime, repeatEvery);

If you want to be able to cancel, then use the TimerTask as a variable. The TimerTask class has the method cancel.

greedybuddha
  • 7,488
  • 3
  • 36
  • 50
1

You may want to have a look at ScheduledThreadPoolExecutor. It is an implementation of ScheduledExecutorService, which has the ability to schedule periodically.

fge
  • 119,121
  • 33
  • 254
  • 329