-3

I have encountered a strange execution while testing my knowledge about threads haha.

I have the following class:

public class ThreadTest {

    public static void main (String[] args){
        Thread t7 = new Thread(() -> {
            while (!Thread.interrupted()) {
                System.out.println("t7 executing...");
            }
            System.out.println("t7 stopped!");
            }
        );
        t7.start();
        for (int i = 0; i<10; i++){
            System.out.println("Waiting for t7 to be interrupted...");
        }
        t7.interrupt();
        System.out.println("t7.isInterrupted: " + t7.isInterrupted());
        System.out.println("t7.isInterrupted at finish: " + t7.isInterrupted());
}

One the outputs from the execution of the main method was the following:

Waiting for t7 to be interrupted...
.
.
.
Waiting for t7 to be interrupted...
t7.isInterrupted: true
t7.isInterrupted at finish: false
t7 executing...
t7 stopped!

I don't understand why there is also that "t7 executing..." there, since from the outputs I would expect only "t7 stopped!".

Christian
  • 1
  • 3
  • 1
    Your code was at the `println("Executing...")` part when it got interrupted, so that code still ran, then the `while` loop checked the status of the interrupt flag, then "stopped" got printed. – markspace Jul 04 '23 at 20:26
  • Why do you think that output is not generated by that code? – Christian Jul 04 '23 at 20:59
  • @markspace I don't understand how it is possible though, since t7.isInterrupted at finish: false was given in output before "t7 executing" and then "t7 stopped"... – Christian Jul 04 '23 at 21:05
  • An interrupt is a flag, it can be set and will be true but the code hasn't actually tested it yet in the `while` loop. – markspace Jul 04 '23 at 21:24
  • Why I think that output is not generated by that code? Exactly because of the *errors* you edited: see [here](https://i.stack.imgur.com/VPKY8.png) – user16320675 Jul 04 '23 at 21:38
  • 1
    NB `Thread.interrupted()` clears the interrupted status of the thread. – user207421 Jul 05 '23 at 00:02

1 Answers1

-1

Threading can produce confusing results sometimes, as the concept of threading itself is almost counter-intuitive to the concept of "programming".

Firstly, here is the output I got from executing the code.

Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
t7 executing...
t7 stopped!
t7.isInterrupted: true
t7.isInterrupted at finish: false

You can break down the execution of your statements in a procedural fashion.

You first assign a new object to t7, and then flag for its execution with the start method.

Thread t7 = new Thread(() -> {
    while (!Thread.interrupted()) {
        System.out.println("t7 executing...");
    }
    System.out.println("t7 stopped!");
}
);
t7.start();

Then, a for-loop will iterate 10 times, printing out some text to the standard-out.

for (int i = 0; i<10; i++){
    System.out.println("Waiting for t7 to be interrupted...");
}

Generally, you should expect to see different outputs within the standard-out here, since there are multiple threads appending data, and the println method sets a lock on System#out when it prints the data.

Here is the source code for println.
GitHub – jdk/src/java.base/share/classes/java/io/PrintStream.java.

Continuing further, the lock on System#out will have been released, so the t7 thread will print out "t7 executing...".

while (!Thread.interrupted()) {
    System.out.println("t7 executing...");
}

Your next statement is an interrupt call, to t7.
Again, generally you will see mixed results here, in terms of which statement of either thread will be executed first.

For example, you may see it print "t7 executing...", additionally.

t7.interrupt();

And, this is followed by two println calls.

System.out.println("t7.isInterrupted: " + t7.isInterrupted());
System.out.println("t7.isInterrupted at finish: " + t7.isInterrupted());

Your question is,

'... I don't understand why there is also that "t7 executing..." there, since from the outputs I would expect only "t7 stopped!".'

You are implying that the conditional statement for the t7 while-loop will not have been met, thus will skip the code block.

This will vary from each execution, although in this application, you will most likely receive the same result every time.

The reason is because the for-loop on your local thread is providing enough time for the t7 code to execute—they are working concurrently, and not in alternation.

For example, if you increase the priority of the t7 thread, you will see a different result—the default is 5, of 10.

t7.setPriority(10);
t7.start();

Output

Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
t7 executing...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
Waiting for t7 to be interrupted...
t7 executing...
t7 stopped!
t7.isInterrupted: true
t7.isInterrupted at finish: false

Here is the Java tutorial on threading, which will provide some insight to your specific question.
Lesson: Concurrency (The Java™ Tutorials > Essential Java Classes).

Reilas
  • 3,297
  • 2
  • 4
  • 17