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