Reputation: 548
Preface: I'm learning Java and not very experienced. My sincere apologies if 1) I'm going about this in a stupid way or 2) My question is unclear. I am eager to learn if my approach is all wrong so please try to show me the light instead of simply telling me I'm in the dark(I'm already well aware I'm surrounded by darkness lol). I will be happy to update/edit this post with any additional information you need, just please ask me. I've tried searching for this but either I'm using the wrong keywords or it's just too stupid a question for anyone to ask.
class NetworkingThread implements Runnable {
@Override
public void run() {//Need this to throw SocketException every 10ms
try {
DatagramPacket dataPacket = receive(ds);//networkIO blocking
//do something
this.run();//recursive call
}
catch (SocketException | SocketTimeoutException e0){
//do something
this.run();//recursive call
}
catch (Exception e1) {
e1.getMessage();
}
}
}
The Problem: The catch block needs to be run at least every 10ms. Cannot use DatagramSocket.setSoTimeout() alone because exception needs to be thrown 10ms after last catch block execution completed not 10ms from last packet received.
My plan: Have the catch block start another thread that will sleep(10) before closing the socket for receive(ds) so that the catch is thrown in my NetworkingThread at the proper time.
Question: Is it better to create a new thread each time I need to start the 10ms counter? Or start one thread and pause execution(not with deprecated API) after it's done it's task and wait for an interrupt to restart it? Examples of what I'm thinking below. Any alternative solutions are welcome.
class TimerThreadOne implements Runnable {
@Override
public void run() {
try {
Thread.currentThread().sleep(10);
//close socket or interrupt thread in some way
}
catch (Exception e) {
e.getMessage();
}
}
}
class TimerThreadTwo implements Runnable {
@Override
public void run() {
try {
Thread.currentThread().sleep(10);
//close socket or interrupt thread in some way
Thread.currentThread().sleep(1000000);//sleep until interrupted
}
catch (InterruptedException eInterrupt){
this.run();//recursive call
}
catch (Exception e) {
e.getMessage();
}
}
}
Upvotes: 1
Views: 238
Reputation: 4024
Have a look at ScheduledThreadPoolExecutor which already provides the facility what you look to achieve.
Your code should look something like below.
ScheduledExecutorService executor = Executors.newScheduledThreadPool(someValue);
executor.scheduleWithFixedDelay(new SomeThread(), 0, 10, TimeUnit.MILLISECONDS);
Class SomeThread
will implement Runnable
and contain the business logic; without any consideration of scheduling, re-run etc. apart from any exception handling legitimate to business / system requirements.
P.S.: In general it is not recommended to use Exception
as flow control.
EDIT
Timeout waiting on a long running task
ScheduledExecutorService executor = Executors
.newScheduledThreadPool(10);
ScheduledFuture<?> result = executor.scheduleWithFixedDelay(() -> {// do
// something
}, 0, 10, TimeUnit.MILLISECONDS);
try {
// this will timeout the task after 5ms.
result.get(5, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
// handle exception
result.cancel(true);
}
I took liberty to assume that you are on Java 8
Upvotes: 1