使用按钮无法停止线程(多线程)

3
我希望您能帮助我翻译一下关于IT技术的内容。需要翻译的内容是如何在另一个类中使用停止按钮来停止多个线程。我尝试使用布尔函数来停止线程,但它不起作用。当用户点击停止按钮时,线程仍在运行,我该如何解决这个问题?


以下是主要的类:

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);
        }
    }   
}

这是关于线程的内容。
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{
    ...
}

2
了解Java命名规范。下划线只用于SOME_CONSTANT;而不是类名。学习数组或列表 - 每当您开始命名变量a1,a2等等时,您正在做一些错误的事情。当然,变量名以小写字母开头。违反这些规则会使任何Java程序员难以阅读您的代码! - GhostCat
2个回答

1
你有两个Main_Thread实例:
Thread MAIN_THREAD = new Thread(new Main_Thread());
private Main_Thread mt = new Main_Thread();

你正在阻止一个,但观察另一个。

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

只需使用单个实例:

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

你还应该确保在停止方法中对paused的更新在其他线程中可见。你应该使停止方法synchronized(或使用AtomicBoolean,或使用适当的线程间信号传递方式,如互斥锁或信号量)。

0

我看到了多个原因,解释为什么它不起作用。

  1. ElevatorSystem.mt 是另一个实例的 Main_Thread,就像被 ElevatorSystem.MAIN_THREAD 使用的那个一样。
  2. 我没有看到任何地方启动了 MAIN_THREAD
  3. Main_Thread 期望它的标志 pauseThreadFlag 在停止时为 false,但是 Main_Thread.stopThread 将其设置为 true
  4. Main_Thread.checkForPaused 调用 wait,但我没有看到任何地方唤醒它。
  5. 我不明白为什么停止 ElevatorSystem.MAIN_THREAD 应该同时停止其他线程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接