如何在Java中停止线程

如何在Java中停止线程,java,multithreading,thread-safety,threadpool,interruption,Java,Multithreading,Thread Safety,Threadpool,Interruption,我正在编写一个程序,生成一个介于1到1000之间的随机数。然后,它使用一个包含三个线程的线程池来搜索更宽的1到1000范围内的某些数字范围。线程检查其范围内的每个数字,并将其与随机目标数字进行比较,如果匹配,则发送到控制台的消息会这样说。如果数字不匹配,这也会反映在发送到控制台的消息中。我试图找出一旦达到目标数字,如何结束该计划,而不是继续分析数字,即使目标已经找到。多谢各位 这是FindIt类: /** fill in later */ public class FindIt extends

我正在编写一个程序,生成一个介于1到1000之间的随机数。然后,它使用一个包含三个线程的线程池来搜索更宽的1到1000范围内的某些数字范围。线程检查其范围内的每个数字,并将其与随机目标数字进行比较,如果匹配,则发送到控制台的消息会这样说。如果数字不匹配,这也会反映在发送到控制台的消息中。我试图找出一旦达到目标数字,如何结束该计划,而不是继续分析数字,即使目标已经找到。多谢各位

这是FindIt类:

/** fill in later */
public class FindIt extends Thread
{
    private int numToFind;
    private int numToStart;
    private int numToEnd;

    public FindIt( int nF, int nS, int nE )
    {
        numToFind = nF;
        numToStart = nS;
        numToEnd = nE;
    }

    public void run()
    {
        int counter = 0;

        int numAt = numToStart;

        for ( int i = 0; i < ( numToEnd - numToStart ) + 1; i++ )
        {
            counter++;

            if ( counter == 10 )
            {
                counter = 0;
                Thread.yield();
            }

            if ( numAt++ == numToFind )
            {
                System.out.println( "The target number, " + numToFind + ", has been found by " + Thread.currentThread().getName() + "." );
            }

            else
            {
                System.out.println( Thread.currentThread().getName() + " has analyzed the number " + ( numAt - 1 ) + " - not the target number." );
            }

        }   
    }
}

需要做两件事:

通过检查Thread.currentThread.isInterrupted并在检测到中断时返回任务,使您的任务对中断做出响应

使用ExecutorService的shutdownNow方法中断当前正在运行的任务。shutdown方法使执行器停止接收新任务,但让已提交给执行器的任务运行到完成

不要为此对线程进行子类化,您应该扩展Runnable或Callable,以便定义提交给执行器的任务。子类化线程意味着任务分配OS线程,这是不必要的,因为实际线程已经在线程池中创建。对于本例,由于您在任务中计算一个数字,因此使用Callable可能是有意义的

java.util.concurrent中有一个现有的类是为这种事情设计的。中给出了在找到答案后取消任务的示例

FindIt已更改以检测中断:

public class FindIt implements Runnable
{
    private int numToFind;
    private int numToStart;
    private int numToEnd;

    public FindIt( int nF, int nS, int nE )
    {
        numToFind = nF;
        numToStart = nS;
        numToEnd = nE;
    }

    public void run()
    {
        int counter = 0;

        int numAt = numToStart;

        for ( int i = 0; i < ( numToEnd - numToStart ) + 1; i++ )
        {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println(Thread.currentThread().getName() 
                + " detected interruption, exiting");
                return;
            }
            counter++;

            if ( counter == 10 )
            {
                counter = 0;
                Thread.yield();
            }

            if ( numAt++ == numToFind )
            {
                System.out.println( "The target number, " + numToFind + ", has been found by " + Thread.currentThread().getName() + "." );
            }

            else
            {
                System.out.println( Thread.currentThread().getName() + " has analyzed the number " + ( numAt - 1 ) + " - not the target number." );
            }

        }   
    }
}

需要做两件事:

通过检查Thread.currentThread.isInterrupted并在检测到中断时返回任务,使您的任务对中断做出响应

使用ExecutorService的shutdownNow方法中断当前正在运行的任务。shutdown方法使执行器停止接收新任务,但让已提交给执行器的任务运行到完成

不要为此对线程进行子类化,您应该扩展Runnable或Callable,以便定义提交给执行器的任务。子类化线程意味着任务分配OS线程,这是不必要的,因为实际线程已经在线程池中创建。对于本例,由于您在任务中计算一个数字,因此使用Callable可能是有意义的

java.util.concurrent中有一个现有的类是为这种事情设计的。中给出了在找到答案后取消任务的示例

FindIt已更改以检测中断:

public class FindIt implements Runnable
{
    private int numToFind;
    private int numToStart;
    private int numToEnd;

    public FindIt( int nF, int nS, int nE )
    {
        numToFind = nF;
        numToStart = nS;
        numToEnd = nE;
    }

    public void run()
    {
        int counter = 0;

        int numAt = numToStart;

        for ( int i = 0; i < ( numToEnd - numToStart ) + 1; i++ )
        {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println(Thread.currentThread().getName() 
                + " detected interruption, exiting");
                return;
            }
            counter++;

            if ( counter == 10 )
            {
                counter = 0;
                Thread.yield();
            }

            if ( numAt++ == numToFind )
            {
                System.out.println( "The target number, " + numToFind + ", has been found by " + Thread.currentThread().getName() + "." );
            }

            else
            {
                System.out.println( Thread.currentThread().getName() + " has analyzed the number " + ( numAt - 1 ) + " - not the target number." );
            }

        }   
    }
}

@Ravindrababu的可能重复:请注意,该问题的公认答案不适用于任务在线程池中运行的情况,当使用Executors.Ok时,整个手动滚动的volatile标志方法失败。我收回了我的投票。@Ravindrababu的相关可能重复项:请注意,该问题的公认答案不适用于任务在线程池中运行的情况,当使用Executors时,整个手动滚动的volatile flag方法失败。Ok。我收回了我的投票。这使得关闭现在可以正常工作,但如果线程不立即停止,我不能立即调用它。找到号码后,我该如何打电话给shutdownNow?@B.Freeman:你可以等到有答案再打给shutdownNow。我做了类似的事情,但没有遗嘱执行人。但在这种情况下,我会使用一个未来,并在未来返回后立即调用Shutdownow。还有一个。这使得关机现在可以正常工作,但是如果线程没有立即停止,我不能立即调用它。找到号码后,我该如何打电话给shutdownNow?@B.Freeman:你可以等到有答案再打给shutdownNow。我做了类似的事情,但没有遗嘱执行人。但在这种情况下,我会使用一个未来,并在未来返回后立即调用Shutdownow。还有一个。