Java线程问题

Java线程问题,java,multithreading,Java,Multithreading,我想通过使用布尔字段来停止线程。我实现了一些代码,如下所示: 我的线程类如下所示: public class ParserThread implements Runnable { private volatile boolean stopped = false; public void stopTheThread() { stopped = true; } : : } 下面是从函数start()启动10个线程的主线程 public类Ma

我想通过使用布尔字段来停止线程。我实现了一些代码,如下所示:

我的线程类如下所示:

public class ParserThread implements Runnable {
    private volatile boolean stopped = false;

    public void stopTheThread() {
        stopped = true;
    }
    :
    :
}
下面是从函数start()启动10个线程的主线程

public类Main(){
线程[]线程;
公开作废开始(){
对于(int i=0;i<10;i++){
threads[i]=新线程(new ParserThread());
}       
}
公共停车场(){
//停止所有线程的代码
}
}
现在我想调用ParserThread的stop方法来设置“stopped=true”来停止线程。我想这件事要做的所有10线程


我怎样才能称之为stop方法。我希望它在Main类的stopAllThreads()方法中完成。

您必须保留ParserThread对象本身:

public class Main() {
    ParserThread[] parserthreads = new ParserThread[10];

    public void start() {
        for(int i = 0; i < 10; i++) {
            parserthreads[i] = new ParserThread();
            new Thread(parserthreads[i]).start();
        }       
    }

    public void stop() {
        for (int i = 0; i < 10; i++) {
            parserthreads[i].stopTheThread();
        }
    }
}
另外,正如其他人所指出的,
stopTheThread()
在类
Thread
上无用地复制了
interrupt
方法,因此您最好的选择是:

public class Main() {
    Thread[] parserthreads = new Thread[10];

    public void start() {
        for(int i = 0; i < 10; i++) {
            parserthreads[i] = new Thread(new ParserThread());
            parserthreads[i].start();
        }       
    }

    public void stop() {
        for (int i = 0; i < 10; i++) {
            parserthreads[i].interrupt();
        }
    }
}
public类Main(){
Thread[]parserthreads=新线程[10];
公开作废开始(){
对于(int i=0;i<10;i++){
parserthreads[i]=新线程(new ParserThread());
parserthreads[i].start();
}       
}
公共停车场(){
对于(int i=0;i<10;i++){
parserthreads[i].interrupt();
}
}
}
然后在ParserThread中,尽可能频繁地调用if(Thread.currentThread().isInterrupted())。

1)不需要额外的易失性变量来通知线程停止;这就是为什么要打断别人。在线程Runnable的run()方法中,您可以

while (!Thread.currentThread().isInterrupted()) {
    // do whatever your thing is
    // some things, like sleeping, can throw InterruptedException when
    // interrupted, so
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        break;
    }
}
// clean up here
2) 然后,要要求线程进程停止,只需

threads[i].interrupt();
瞧。

看看这个框架。如果使用,则可以将所有工作作为
可运行文件提交
。executor框架将跟踪所有这些线程,所有托管线程将通过
shutdownNow()
方法接收关闭请求(interupt)

线程必须正确处理中断。有关更多信息,请参阅


通常,使用Executor框架来管理线程集、收集结果、处理异常等更容易。

这里是使用。与直接操作线程相比,它需要更少的代码,并提供了两种停止工作线程的替代方法。它还允许您潜在地捕获每个工作项的结果(如果要使用可调用实例而不是可运行实例)。即使您不希望捕获显式返回值,它也允许您轻松地将任何异常打包回主线程

// Array of Runnables that we wish to process.
ParserThread[] parserThreads = ...

// Create executor service containing as many threads as there are Runnables.
// (Could potentially have less threads and let some work items be processed
// sequentially.)
ExecutorService execService = Executors.newFixedThreadPool(parserThreads.length);

// Submit each work item.  Could potentially store a reference to the result here
// to capture exceptions.
for (ParserThread runnable : parserThreads) {
  execService.submit(runnable);
}
然后,要关闭所有线程,您可以调用:

executorService.shutDown(); // Initiates an orderly shut-down of the service.
。。。或

executorService.shutDownNow(); // Stops all tasks, interrupting waiting tasks.
}

Declare stopped static,当您将其设置为false时,所有ParserThread runnables都将看到可见性

只要调用

ParserThread.stopTheThread();

编辑,因为这只会影响已停止布尔标志的状态。它显然不会为您停止线程:)

我想调用thread类的stoptTheThread()方法,以便设置字段“stopped=true”否!永远不要调用Thread.stop()!虽然这个答案确实解决了您最初的问题,但我认为它是错误的(因为Java已经提供了一个协作中断(),所以您不需要额外的机器)。警告:Thread.interrupted()和Thread.isInterrupted()之间有细微的区别。前者是一种静态方法,重置中断标志。后者是非静态的,不会重置中断标志。谢谢!当然,你是对的,这就是我的意思。更正。当然,这假设所有代码都正确地处理和传播InterruptedException,而很多代码都没有,这要归功于检查异常的奇妙效果,这会导致天真的程序员吞下它们(我在早期也包括在内)。SM,这是一个显示InterruptedException正确处理的示例。这段代码是如何假定的?@Jonathan,当您退出循环时,您最初使用的Thread.interrupted()仍然有效(因此可能此时也退出run()方法);i、 因此,在这种情况下重置中断标志状态可能更为正确。我认为这最终是正确的答案,尽管了解我的信息也很好。Java中没有那么多线程原语,即使您使用的是Doug Lea优秀的util.concurrent工具,理解它们也是件好事。@Brian:你比我强。。。不应该在一个有效的例子上浪费时间!有一件事-API没有提到shutDown()将发出任何中断,而是将等待当前活动任务完成。shutDownNow()通常会调用interrupt()。@Adamski-well-spotted re。shutdownNow()。现在更正。这次是Thx+1。我们努力不再使用光头线。新的java.util.concurrency工具太有用了,不容忽视,而且,正如这个问题所说明的,秃头线程是笨拙的、令人困惑的,有时甚至是危险的。@Pedro-那太可怕了。。。即使是周五下午!
executorService.shutDownNow(); // Stops all tasks, interrupting waiting tasks.
public class ParserThread implements Runnable {
private static volatile boolean stopped = false;

public static void stopTheThread() {
    stopped = true;
}
ParserThread.stopTheThread();