所以我围绕着多线程,我做了一个非常基本的程序来玩。这个想法只是我会开始几个线程,每个线程都会向下(递减)到零,此时一个将被宣布为胜利者而其他人将立即停止。我使用了一个布尔标志,它终止了其他线程,但有时它们继续运行一段时间(我想直到他们在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();
}
答案 0 :(得分:2)
基本上我只想要一个帖子来说"好的,每个人都会停止你现在正在做的事情"。
Java应用程序无法对自己执行此操作。调试器可能会这样做。 (当然,JDWP协议有一个命令来冻结目标JVM中的所有线程......)
在Java应用程序中最接近的是遍历ThreadGroups和Threads树,并将不推荐使用的Thread.suspend()
方法应用于每个Thread。 (注意不要暂停当前线程...)但是挂起方法很危险(请参阅javadocs),并且无法保证您将在遍历中看到所有线程。当然,这个(假设的)程序不是即时的。
答案 1 :(得分:1)
使用仅可声明一次且仅第一次声明的标记。其中一个问题是使用AtomicBoolean
方法的compareAndSet()
。要停止其他线程,您可以发送interrupt()
。
(Java曾经拥有停止和终止线程的权力,但这会导致问题。中断是使线程脱离正常执行的唯一可靠方法。)
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();
}
}
}