我有以下课程,我通常会运行大约10个帖子
public class MyClass implements Runnable {
private volatile Device device = null;
public MyClass(Device device) {
this.device = device;
}
@Override
public void run() {
while (true) { // <--- I do know that the "true" has to be changed to a Boolean
try {
Worker worker = new Worker();
worker.work();
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
}
在我的主要内容中我开始像这样的线程
for (int i = 0; i < 2; i++) {
(new Thread(new MyClass())).start();
}
这是一个基于控制台的程序。结束该计划最可靠的方法是什么?我认为最好的方法是将while (true)
更改为while (Boolean)
并以某种方式更改所有线程的布尔值,然后当循环结束时,程序将正常结束。
答案 0 :(得分:0)
这里我通过等待用户输入结束它,但你可以改变它以从任何地方触发停止方法
public static void main(String[] args) {
List<MyClass> myThreads = new ArrayList<>();
for (int i = 0; i < 2; i++) {
MyClass myClass = new MyClass();
Thread t = new Thread(myClass);
t.start();
myThreads.add(myClass);
}
Scanner in = new Scanner(System.in);
in.next();
for(MyClass t : myThreads){
t.stop();
}
}
class MyClass implements Runnable {
private Boolean flag;
public MyClass() {
this.flag = true;
}
@Override
public void run() {
while (flag) { // <--- I do know that the "true" has to be changed to a Boolean
try {
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
public void stop(){
this.flag = false;
} }
答案 1 :(得分:0)
简单的方法是将所有线程存储在一个集合中,并在最后将make循环连接起来 请注意,这不是最正常的方法,也不是最有效的方法。
在您的主页:
HashSet<Thread> threads = new HashSet();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(new MyClass());
threads.add(t);
t.start();
}
for (Thread thread: threads) {
thread.join();
}
答案 2 :(得分:0)
以下代码使用执行程序服务来修复任何时候运行的线程数,它提供了一个Future对象,它还可以告诉您线程何时正常关闭。它们也共享一个关闭对象。这为您提供了更多的灵活性,因为执行程序服务可以让您在任何时候优雅地决定运行多少个线程。
首先,我们创建了一个共享关闭对象,它将通知所有线程关闭的时间。将有一个这样的实例,每个线程都有一个副本。
public static class Shutdown {
private boolean running;
public void shutdown() {
this.running = false;
}
public boolean isRunning() {
return running;
}
}
接下来让我创建一个虚拟线程,它只会在运行时永远休眠。显然你可以用你自己的线程替换它来做一些有用的事情。
public static class MyClass implements Runnable {
final Shutdown shutdown;
public MyClass(Shutdown shutdown) {
this.shutdown = shutdown;
}
@Override
public void run() {
while (shutdown.isRunning()) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Did not gracefully shut down");
}
}
System.out.println("Thread in program ended!");
}
}
}
现在,对于将运行一切的主类,这就是魔术发生的地方。
public class Main {
public static void main(String[] args) {
//run exactly 10 threads at a time
ExecutorService executorService = Executors.newFixedThreadPool(10);
//this is how we shut it down
Shutdown globalShutdown = new Shutdown();
//start up the 10 threads
List<Future<?>> futures = new ArrayList<>();
for(int i = 0; i< 10; i++)
futures.add(executorService.submit(new MyClass(globalShutdown)));
//gracefully shut them down
globalShutdown.shutdown();
try {
//wait for them all to shutdown
for(Future<?> future : futures)
future.get();
} catch (InterruptedException e) {
throw new IllegalStateException("This should never happen");
} catch (ExecutionException e) {
throw new IllegalStateException("This should never happen");
}
//everything got shutdown!
}
在实践中,您可能还想处理由于错误而导致线程无法正常结束的情况。您可能希望添加超时而不是永久停止,如果超过该超时,则只需强制终止所有剩余的线程。为此,用这个替换上面的try-catch块。
try {
//wait for them all to shutdown
boolean timedout = false;
for(Future<?> future : futures) {
if( !timedout ) {
try {
future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
timedout = true;
}
}
if(timedout) {
future.cancel(true);
}
}
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("This should never happen");
}