这是我应该停止Java中的线程的方式吗?

时间:2016-02-26 01:20:21

标签: java multithreading

我的老师告诉我不要使用stop(),而是在Thread类中使用这种方式:

public void pararHilo() { 
    stopHilo = true; 
}

public void run() {
    while (!stopHilo) 
        c++; 
} 

据我所知,当调用pararHilo()时,循环结束,因此它退出run()方法并且Thread死掉。 问题是我有一台相当不错的笔记本电脑,当用这段代码进行测试时(这里和学校),我的机器变得迟钝,我必须关闭Eclipse ......我错过了什么?

整个代码

public class EjemploHilo { 

    public static void main(String args[]) { 

        HiloPrioridad h1 = new HiloPrioridad(); 
        HiloPrioridad h2 = new HiloPrioridad();
        HiloPrioridad h3 = new HiloPrioridad();

        //el hilo con mas prioridad contara mas deprisa que los demas
        h1.setPriority(Thread.MAX_PRIORITY); 
        h2.setPriority(Thread.NORM_PRIORITY);
        h3.setPriority (Thread.MIN_PRIORITY); 

        h1.start(); h2.start(); h3.start();

        try { 
            Thread.sleep(2000); 
            } catch (Exception e) { } 

        h1.pararHilo(); 
        h2.pararHilo(); 
        h3.pararHilo(); 

        System.out.println("h1 (Prioridad Maxima): " + h1.getContador()); 
        System.out.println("h2 (Prioridad Normal): " + h2.getContador()); 
        System.out.println("h3 (Prioridad Minima): " + h3.getContador());

        } 

}

public class HiloPrioridad extends Thread { 

    private int c = 0; 
    private boolean stopHilo= false; 

    public int getContador() {
        return c; 
    }

    public void pararHilo() { 
        stopHilo = true; 
    }

    public void run() {
        while (!stopHilo) 
            c++; 
    } 

}

4 个答案:

答案 0 :(得分:3)

您的while循环应检查以下内容:

[['11:15', '12:15', '13:15'], 
 ['18:15', '19:15', '20:15'], 
 ['12:00', '13:00'], 
 ['14:00', '15:00', '16:00'], 
 ['12:00']]

这样,客户端可以调用while (!Thread.currentThread().isInterrupted() && /* more work to do */) { // do more work } ,将线程的中断状态设置为Thread.interrupt()

  

注意:当在阻塞诸如睡眠或等待等呼叫的线程上调用中断方法时,阻塞调用将由true终止,应该处理:

InterruptedException

答案 1 :(得分:1)

是的,但您需要信号量变量为volatile

private volatile stopHilo;

否则正在运行的线程可能永远看不到分配。

此外,像这样的紧密循环应该定期暂停Thread.sleep()或产生Thread.yield()

答案 2 :(得分:1)

使用请求变量来停止线程仅适用于可以高速率轮询变量的情况。

如果您正在调用诸如Thread.sleep()之类的方法或等待其他程序,那么您的程序将会变慢并且请求变量的高速轮询不适合。

而是使用Thread.interrupt()来停止线程。

您可能会发现Oracle's guide为什么不推荐使用Thread.stop。

您可能面临的另一个问题是Thread请求变量不是volatile,请确保您已将其声明为预期用途。

private volatile boolean stopHilo = false;

答案 3 :(得分:0)

我认为您需要注意以下事项:

1)线程优先级。您将其中一个子线程设置为HIGH_PRIORITY,而您的主线程未设置,因此它应该使用normal。因此,您的一个子线程的优先级高于主线程。由于你有一个无限循环,当你的主线程可能正在等待时(因为它的优先级较低),这会占用你的大量CPU。

2)就像其他人所说的那样,我会在你的子线程运行方法循环中放一个小睡眠。这将为主线程(和其他人)提供执行时间。

3)我个人也没有在实践中直接提到变量。通常,我会使用get方法,即使在while循环中也会返回变量。这只是通常使用的标准编码实践。如果此get / set方法对线程很重要,那么您也可以使它们同步。通过这种方式,一个集合不可能在百万分之一秒内发生获取正在发生,反之亦然。一个额外的保护(取决于您的应用程序使用)。作为所有主题,这些类型的决策需要根据具体情况进行,但需要考虑。您仍然可以调用pararHilo并调用set方法,或者您的主线程可以调用setStopHilo(false)。

你可以尝试一下这三件事,看看它对你有用吗?