如何阻止所有活动线程运行

时间:2014-06-14 04:06:20

标签: java multithreading

所以我围绕着多线程,我做了一个非常基本的程序来玩。这个想法只是我会开始几个线程,每个线程都会向下(递减)到零,此时一个将被宣布为胜利者而其他人将立即停止。我使用了一个布尔标志,它终止了其他线程,但有时它们继续运行一段时间(我想直到他们在while循环中检查是否运行仍然是真的)。​​

我尝试过中断,但我的理解是这些仅适用于正在休眠,等待等的线程,而且我使用的线程一直在运行。我已经使用过system.exit(1),但这并没有阻止它们,至少不会立即停止。只是想知道更有经验的人会做什么?基本上我只想要一个帖子说“好的,每个人都会停止你现在正在做的事”。

以下是代码:

可运行的课程

public class ThreadRunnable implements Runnable {

    private static boolean run;
    private int tick;

    public ThreadRunnable() {
        run = true;
        tick = 5;
    }

    public void run() {
        Thread t = Thread.currentThread();
        while (run) {
            tickDeduction();
            if (tick == 0) {
                System.out.println("Thread " + (Thread.currentThread().getId()) + " WINS");
                this.run = false;
                return;
            }
        }
    }

    public synchronized void tickDeduction() {
        System.out.println("Thread " + (Thread.currentThread().getId()) + " is at tick " + this.tick);
        this.tick--;
    }
}

主要类

     public static void main(String[] args) {
        ThreadRunnable runnableBlue = new ThreadRunnable();
        ThreadRunnable runnableRed = new ThreadRunnable();
        Thread teamBlue = new Thread(runnableBlue); 
        Thread teamRed = new Thread(runnableRed);
        teamBlue.start();
        teamRed.start();
    }

2 个答案:

答案 0 :(得分:2)

  

基本上我只想要一个帖子来说"好的,每个人都会停止你现在正在做的事情"。

Java应用程序无法对自己执行此操作。调试器可能会这样做。 (当然,JDWP协议有一个命令来冻结目标JVM中的所有线程......)


在Java应用程序中最接近的是遍历ThreadGroups和Threads树,并将不推荐使用的Thread.suspend()方法应用于每个Thread。 (注意不要暂停当前线程...)但是挂起方法很危险(请参阅javadocs),并且无法保证您将在遍历中看到所有线程。当然,这个(假设的)程序不是即时的。

答案 1 :(得分:1)

使用仅可声明一次且仅第一次声明的标记。其中一个问题是使用AtomicBoolean方法的compareAndSet()。要停止其他线程,您可以发送interrupt()

(Java曾经拥有停止和终止线程的权力,但这会导致问题。中断是使线程脱离正常执行的唯一可靠方法。)

https://ideone.com/1F3bkH

import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;

public class Main {
    public static void main(String[] args) {
        final AtomicBoolean flag = new AtomicBoolean(false);

        final Thread[] runners = new Thread[5];

        final Random random = new Random();

        for (int i = 0 ; i < runners.length; i++){
            runners[i] = new Thread("Runner # " + i){
                @Override
                public void run() {
                    try {
                        // wait for random time
                        Thread.sleep(1000 + random.nextInt(1000));

                        // try to claim the flag
                        boolean claimed = flag.compareAndSet(false,true);

                        if(claimed){
                            System.out.println(this.getName() + " has won the race.");

                            // interrupt others
                            for (Thread t : runners){
                                if(!t.equals(this)){
                                    t.interrupt();
                                }
                            }
                        }else {
                            System.out.println(this.getName() + " has very closely lost the race.");
                        }

                    } catch (InterruptedException e) {
                        System.out.println(this.getName() + " has lost the race.");
                    }
                }
            };
        }

        // get set go
        for (int i = 0 ; i < runners.length; i++){
            runners[i].start();
        }
    }
}