有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java线程无法停止

为什么我的线程不能停止

 class Threadz {

    class runP implements Runnable {
        int num;
        private volatile boolean exit = false;
        Thread t;
        public runP() {
            t = new Thread(this, "T1");
            t.start();
        }

        @Override
        public void run() {
            while(!exit) {
                System.out.println(t.currentThread().getName()+": "+num);
                num++;  
                try {
                    t.sleep(200);   
                } catch(InterruptedException e) {}
            }
        }
        public void stop() {
            exit = true;
        }
    }

    public static void main(String[] a) {
        runP rp = new Threadz().new runP();
        if(rp.num == 1) {rp.stop();}
    }

}

如果我使用rp.num==0,线程可以立即停止。但是,为什么当我更改rp.num==x(x是任何大于0的数字)时线程不能停止?请帮我解决这件事。。。谢谢你的帮助


共 (4) 个答案

  1. # 1 楼答案

    检查rp.num == 1必须正好发生在rp.num正好是一的点上,这是不太可能的

    main方法中,您启动一个线程,该线程每200毫秒增加一次num。之后,您将检查num == 1,但这段代码的具体执行时间取决于许多您无法真正控制的因素(操作系统的调度等)。这可能在10毫秒之后(值为1),但也可能在300毫秒之后(值已经为2)。另外,线程何时准确启动也不确定。因此,您的线程也可能仅在测试之后启动。您可以用一个简单的print语句System.out.println(rp.num)替换checkif(rp.num == 1) {rp.stop()};来轻松测试这一点。如果您在打印之前再等待一段时间,您可能会更好地了解我所说的内容

    假设您想从外部阻止runnable,我建议使用类似Observer pattern的东西:

    class MyRunnable implements Runnable {
    
        private final MyListener l;
        private volatile boolean exit;
        int num;
    
        public MyRunnable(MyListener l) {
            this.l = l;
            exit = false;
        }
    
        @Override
        public void run() {
            while(!exit) {
                System.out.println(t.currentThread().getName()+": "+num);
                l.check(num++);
                try {
                    t.sleep(200);   
                } catch(InterruptedException e) {}
            }
        }
    
        public void stop() {
            exit = true;
        }
    }
    
    class MyListener {
    
        private final threshold;
    
        public MyListener(int x) {
            this.threshold = x;
        }
    
        public void check(MyRunnable r, int num) {
            if (num >= threshold)
                r.stop();
        }
    
    }
    

    你的主要方法是

    public static void main(String[] args) {
        MyListener l = new MyListener(1);
        Runnable r = new MyRunnable(l);
        new Thread(r).start();
    }
    
  2. # 2 楼答案

    我敢肯定,如果你多次运行这个程序,当程序真正停止运行时,就会出现这种情况

    原因是在运行程序时,执行的机会要大得多

    if(rp.num == 1) {rp.stop();}
    

    run()方法中的num++之前更改值

    然而,您可能会偶然遇到这样一种情况,即在主方法中的if语句之前执行run方法中的循环

    确保发生这种情况的一种方法是持续检查以下情况:

    例如

    public static void main(String[] a) {
       runP rp = new Threadz().new runP();
    
       while(true){
          if(rp.num == 1) {
             rp.stop(); 
             break;
          }
       }
    }
    
  3. # 3 楼答案

    在线程开始执行run方法之前执行下面的语句

    if(rp.num == 1) {rp.stop();}
    

    添加线程。在执行上述语句之前执行sleep,它可以正常工作,因为它将在启动循环后执行此语句

      public static void main(String[] a) {
        runP rp = new Threadz().new runP();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        if(rp.num > 1) {rp.stop();}
    }
    

    我做到了>;1.进行测试

  4. # 4 楼答案

    因为此代码不是在线程的run()方法中执行的:

        runP rp = new Threadz().new runP();
        if (rp.num == 1) {
            rp.stop();
        }
    

    它与0一起工作,因为int的默认值为0。 但这并不一定在应用程序的所有执行中都是正确的,因为runP的线程可以在检查之前运行并增加numif (rp.num == 0)

    在runP线程的run方法中移动停止条件:

    @Override
    public void run() {
        while(!exit) {
            System.out.println(t.currentThread().getName()+": "+num);
            num++;  
            try {
                t.sleep(200);   
            } catch(InterruptedException e) {}
    
            if (rp.num == 1) {
              exit = true;
            }
        }
    }