Anonimni Gost
Anonimni Gost

Reputation: 11

Daemon thread set to enter a command to stop user threads

I need help solving this problem which I have, so if anyone had a similar problem, that will help me a lot. The problem is related to concurrent programming in Java.

I have a Ball class, and a Test class. I have created a daemon thread that requires input, and if the command 'STOP' is entered, all threads stop running, and the program should print "Jumping aborted" and the program should terminate. On the other hand, if I do not enter anything, it is necessary for the program to print that "All balls have jumped", and for the program to finish working.

Here's my code:

Ball.java
public class Ball extends Thread {
    public int id;
    public static volatile boolean flag = false;
    public static volatile Object lock = new Object();
    public boolean isJumped = false;

    public Ball(int id) {
        this.id = id;
    }

    public void pauseThread() {
        flag = true;
    }

    @Override
    public void run() {
        while (!flag) {
            synchronized (lock) {
                if (flag) {
                    lock.notifyAll();
                    break;
                }
                if (!isJumped) {
                    System.out.println("Ball " + id + " jumping...");
                    isJumped = true;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
Test.java
import java.io.IOException;
import java.lang.reflect.Array;
import java.nio.file.*;
import java.util.*;
import java.util.stream.Collectors;

public class Test
{
   private static volatile boolean on = true;
   public static Object lock = new Object();
   public static void main(String args[])
   {
    List<Ball> balls  =  new ArrayList<>();
    for(int i = 0; i < 50; i++)
    {
        Ball ball = new Ball(i);
        balls.add(ball);

    }
    for(Ball ball : balls)
    {
        ball.start();
    }


    // Create a deamon thread:

    Thread inputThread = new Thread(() -> {
        while (true) {
            Scanner scanner = new Scanner(System.in);
            String input = scanner.nextLine().toUpperCase();

            if (input.equals("STOP")) {
                for (Ball ball : balls) {
                    ball.pauseThread();
                }
                on = false;
                System.out.println("Jumping Aborted...");
                break;
            }
        }

    });
    inputThread.setDaemon(true);
    inputThread.start();


    if (on) {
        for (Ball ball : balls) {
            try {
                ball.join();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
        System.out.println("All balls are jumped...");
    }

}
}

What I want is that when I enter 'STOP' it says "Jumping Aborted", and the program ends. Also, I want when I don't enter anything, it should print "All balls jumped" and the program should end. I find this behavior strange, because if I don't input anything, which causes the program to still wait for me to input something, shouldn't this daemon thread terminate when the other user threads and main thread terminate?

Upvotes: 1

Views: 50

Answers (1)

forty-two
forty-two

Reputation: 12817

Your program is not terminating until you enter STOP, because all the "Ball" threads are still running and waiting for the "flag" variable to become false.

After "jumping", there is no point in keeping the "Ball" thread around, so you should terminate it, perhaps by inserting a break statement in your while loop:

public void run() {
    while (!flag) {
        synchronized (lock) {
            if (flag) {
                lock.notifyAll();
                break;
            }
            if (!isJumped) {
                System.out.println("Ball " + id + " jumping...");
                isJumped = true;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
}

All the "Balls" threads will terminate, one after another, and after that your input daemon thread will also terminate, and finally the entire program.

Upvotes: 0

Related Questions