Temmie
Temmie

Reputation: 127

Thread won't stop using a button(Multithreading)

I want to stop multiple threads using a stop button in another class. I tried using the boolean function in stopping a thread but it won't work. When the user click the stopbutton, the thread is still running, how do i fix this?


This is the main class

public class ElevatorSystem extends javax.swing.JFrame {
    public static int currentFloor = 1;

    Thread ElevatorMove = null;
    Thread PeopleMove = null;
    static Thread RandomPeople = null;
    Thread MAIN_THREAD = new Thread(new Main_Thread());
    private Main_Thread mt = new Main_Thread();
    ...

    public ElevatorSystem() {
        initComponents();
        randWeight();
        this.setResizable(false);
        if(pplw.isEmpty())
            elev_weight = 0;
        else{
            for(int s:pplw)
                elev_weight += s;

        }
        RandomPeople = new Thread(new Randomize_People(EntryFloor1,EntryFloor2,EntryFloor3,EntryFloor4,EntryFloor5));
        RandomPeople.setPriority(Thread.MAX_PRIORITY-1);
    //Start Adding peeoples
        RandomPeople.start();
    }

    ...
    private void btnStopActionPerformed(java.awt.event.ActionEvent evt) {                                        
        //not working...
        if(MAIN_THREAD.isAlive()){
            try {
                mt.stopThread();
            } catch (InterruptedException ex) {
                Logger.getLogger(ElevatorSystem.class.getName()).log(Level.SEVERE, null, ex);
            }
        }else{
            this.setEnabled(false);
            JOptionPane.showMessageDialog(this,"Thread Not Running!","Thread Not Running!",JOptionPane.INFORMATION_MESSAGE);
            this.setEnabled(true);
        }
    }   
}

This is the threads

class Main_Thread implements Runnable{
    ....
    private final Object ElevatorSystem = new Object();
    private boolean pauseThreadFlag = false;

    Main_Thread(){

    }

    Main_Thread(
        JTextField EntryFloor1, JTextField ExitFloor1,
        JTextField EntryFloor2, JTextField ExitFloor2,
        JTextField EntryFloor3, JTextField ExitFloor3,
        JTextField EntryFloor4, JTextField ExitFloor4,
        JTextField EntryFloor5, JTextField ExitFloor5,
        JTextField Ceiling,

        JTextArea Elev1,   JPanel Elev1Container,

        String Elevator_Status, int currentFloor,int elev_weight, ArrayList pplw
    ){
        this.EntryFloor1 = EntryFloor1; this.ExitFloor1 = ExitFloor1;
        this.EntryFloor2 = EntryFloor2; this.ExitFloor2 = ExitFloor2;
        this.EntryFloor3 = EntryFloor3; this.ExitFloor3 = ExitFloor3;
        this.EntryFloor4 = EntryFloor4; this.ExitFloor4 = ExitFloor4;
        this.EntryFloor5 = EntryFloor5; this.ExitFloor5 = ExitFloor5;

        this.Elev1 = Elev1;
        this.Elev1Container = Elev1Container;

        this.Elevator_Status = Elevator_Status;
        this.currentFloor = currentFloor;

        this.elev_weight = elev_weight;

        this.pplw.addAll(pplw);
    }
    @Override
    public void run() {
        System.out.println("Running...");
        System.out.println("Inside Weight: "+pplw);
        while(true){
            checkForPaused();
            //whole process
       }
    }

    private void checkForPaused() {
       synchronized (ElevatorSystem) {
           while (pauseThreadFlag) {
               try {
                   ElevatorSystem.wait();
               } catch (Exception e) {}
           }
       }
    }

    public void stopThread() throws InterruptedException {
        pauseThreadFlag = true;
    }
}

class People_Move implements Runnable{
    ...
}

class Elevator_move_UP implements Runnable{
    ...
}

class Elevator_move_DOWN implements Runnable{
    ...
}

class Randomize_People implements Runnable{
    ...
}

Upvotes: 3

Views: 82

Answers (2)

Andy Turner
Andy Turner

Reputation: 140494

You have two instances of Main_Thread:

Thread MAIN_THREAD = new Thread(new Main_Thread());
private Main_Thread mt = new Main_Thread();

You're stopping one, but observing the other.

if(MAIN_THREAD.isAlive()){
  try {
    mt.stopThread();

Simply use a single instance:

private Main_Thread mt = new Main_Thread();
Thread MAIN_THREAD = new Thread(mt);

You should also ensure that the update to paused in the stop method is visible in other threads. You should make the stop method synchronized (or use an AtomicBoolean, or use a proper way of signalling between threads, like a mutex or semaphore).

Upvotes: 1

mm759
mm759

Reputation: 1424

I see multiple reasons why it does not work.

  1. ElevatorSystem.mt is another instance of Main_Thread as the one used by ElevatorSystem.MAIN_THREAD.
  2. I don't see that MAIN_THREAD is started anywhere.
  3. The class Main_Thread expects it's flag pauseThreadFlag to be false for stopping, but Main_Thread.stopThread sets it to true.
  4. Main_Thread.checkForPaused calls wait, but I don't see a place where it is waked up.
  5. I don't see a reason why stopping ElevatorSystem.MAIN_THREAD should stop other threads, too.

Upvotes: 0

Related Questions