RoboLam
RoboLam

Reputation: 548

Java Threads: Pause/Resume Thread vs Terminiate/Start New Thread

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

Answers (1)

Ammar
Ammar

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 SomeThreadwill 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

Related Questions