-1

Consider this code :-

class A {
    Thread t = new Thread() {
        @Override
        public void run() {
            super.run();
            
            // Tons of statements.... (Set 1)
            
            
            if(/* We don't meet certain requirements for continuing */) {
                
                // Exit and stop the thread and do not execute any following statements after the if block
                
            }
            
            
            // Tons of statements.... (Set 2)
        }
    };
    
    public void run() {
        t.start();
    }
}

class B {
    public static void main(String[] args) {
        A obj = new A();
        obj.run();
    }
}

We start our program with main of class B.

Say that main in class B finishes all it's instructions while Thread t is still executing it's statments in set 1.

Now, there are only two ways for the t to stop. Either it reaches end of statement Set 2 (this will result in thread dying out), or the if block stops the Thread t.

I want to know how can such an if block be implemented ?

If i simply write join(), then the Thread t doesn't seem to execute furthur command but it stays ALIVE and does not dies out (What i have observed from my experiments).

And stop() is depreciated. So what is the proper way to implement the necessary if block. What should the body, so that if certain critera do not meet before continuti, we enter the if block and then the code ends the tread without executing any further instruction (below the if block) and then the Thread DIES immediately.

NOW, CLEARLY A SIMPLE & PROPER SOLUTION IS JUST TO PUT ALL THE SET2 INSTRUCTIONS IN else BLOCK,

but i'd like to know if there is some other proper way to do this.

I am making a text based game and I create multiple instances of Class A. For each instance of A, I have to make such checks at multiple places.

Putting all the further code in else blocks will make the code too nested. Indentation looks bad and it feels like this is not the proper approach.

And it will also help me understand threads better. Starting threads is easy, but stopping them always takes a heavy toll on my brain.

Hokkyokusei
  • 1,021
  • 13
  • 18
  • `obj.run();` -- this is not how to start a thread. You would call `obj.start();`, otherwise your code is running in the same thread that the main method is. Also, why extend Thread in the first place? Shouldn't you be implementing Runnable instead? – DontKnowMuchBut Getting Better Dec 24 '20 at 19:02
  • 1
    `if (condition) { return; }` or `if (!condititon) { /* Set 2 */ }`. Keep in mind that within the `condition` a variable is used that is set by another thread, we need to guarantee inter-htread visibility. – Turing85 Dec 24 '20 at 19:03
  • 1
    Please check the second answer in following thread - better way to signal other thread to stop: https://stackoverflow.com/questions/6859681/better-way-to-signal-other-thread-to-stop – Sergey Terentyev Dec 24 '20 at 19:05

2 Answers2

2

A thread terminates when its run method completes. The return statement terminates a method. Since method run returns no value, simply writing return in the if block will terminate the method and subsequently, the thread.

if(/* We don't meet certain requirements for continuing */) {
    return;
}
Abra
  • 19,142
  • 7
  • 29
  • 41
2

The answer by Abra is correct. Let me add thoughts on avoiding Thread.

Since Java 5, we generally no longer address the Thread class directly. Instead use an executor service. Pass a Runnable or Callable whose code is the task you want performed.

In your main method:

ExecutorService executorService = Executors. … ;

Runnable runnable = () -> {
     // Tons of statements … 
    if( whatever ) 
    {
        return ;  // Method ends. So then thread ends or is returned to thread pool managed by the executor service.
    }
    // …
    // Method ends. So then thread ends or is returned to thread pool managed by the executor service.
};

executorService.submit( runnable ) ; 
… 
executorService.shutdown() ;

In the future, when Project Loom arrives, ExecutorService will be AutoCloseable. So we can use try-with-resources syntax with the executor service. And the try statement will block until all submitted tasks are done (completed or interrupted). The executor service is automatically shutdown at that point.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • It's been long since I have come back to this question to see how stupid I was asking such kind of questions. But it also makes me wanna thank you (which I should have done way too earlier) for this additional tip, that has actually improved the way I handle threads by an exponential factor. – Hokkyokusei Jun 27 '21 at 19:15