如何在 Java 中停止线程
How to stop threads in Java
我正在编写一个生成 1 到 1,000 之间随机数的程序。然后,它使用一个包含三个线程的线程池来搜索更广泛的 1 到 1,000 范围内的特定数字范围。线程检查其范围内的每个数字,并将其与随机目标数字进行比较,如果匹配,则向控制台显示消息。如果数字不匹配,这也会反映在发送到控制台的消息中。我试图弄清楚如何在达到目标数字后结束程序,并且即使已经找到目标也不继续分析数字。谢谢。
这是 FindIt class:
/** 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." );
}
}
}
}
这是包含主要方法的程序:
import java.util.Random; //imports Java's Random class
import java.util.concurrent.*;
/** fill in later */
public class NumberSearch
{
public static void main( String [] args )
{
Random r = new Random(); //creates an instance of the Random class
int randomNum = r.nextInt( 1001 ); //declares the integer randomNum and initilizes it to be a random interger in the range 0 inclusive to 1001 exclusive
ExecutorService executor = Executors.newFixedThreadPool( 3 );
FindIt find1 = new FindIt( randomNum, 0, 349);
FindIt find2 = new FindIt( randomNum, 350, 699);
FindIt find3 = new FindIt( randomNum, 700, 1000);
executor.execute( find1 );
executor.execute( find2 );
executor.execute( find3 );
executor.shutdown();
}
}
需要两件事:
通过检查 Thread.currentThread().isInterrupted()
并在检测到中断时让任务 return 让您的任务响应中断。
使用 ExecutorService 的 shutdownNow 方法中断当前 运行 任务。 shutdown 方法使执行器停止接收新任务,但让已经提交给执行器的任务 运行 完成。
不要为此子class 线程,您应该扩展 Runnable 或 Callable 以定义提交给 Executor 的任务。 Subclassing Thread 意味着任务分配一个 OS 线程,这是不必要的,因为实际线程已经在线程池中创建。对于此示例,由于您正在计算任务中的数字,因此使用 Callable 可能有意义。
java.util.concurrent中已有一个class就是为这种东西设计的。 API documentation for ExecutorCompletionService.
中给出了找到答案后取消任务的示例
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." );
}
}
}
}
我正在编写一个生成 1 到 1,000 之间随机数的程序。然后,它使用一个包含三个线程的线程池来搜索更广泛的 1 到 1,000 范围内的特定数字范围。线程检查其范围内的每个数字,并将其与随机目标数字进行比较,如果匹配,则向控制台显示消息。如果数字不匹配,这也会反映在发送到控制台的消息中。我试图弄清楚如何在达到目标数字后结束程序,并且即使已经找到目标也不继续分析数字。谢谢。
这是 FindIt class:
/** 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." );
}
}
}
}
这是包含主要方法的程序:
import java.util.Random; //imports Java's Random class
import java.util.concurrent.*;
/** fill in later */
public class NumberSearch
{
public static void main( String [] args )
{
Random r = new Random(); //creates an instance of the Random class
int randomNum = r.nextInt( 1001 ); //declares the integer randomNum and initilizes it to be a random interger in the range 0 inclusive to 1001 exclusive
ExecutorService executor = Executors.newFixedThreadPool( 3 );
FindIt find1 = new FindIt( randomNum, 0, 349);
FindIt find2 = new FindIt( randomNum, 350, 699);
FindIt find3 = new FindIt( randomNum, 700, 1000);
executor.execute( find1 );
executor.execute( find2 );
executor.execute( find3 );
executor.shutdown();
}
}
需要两件事:
通过检查
Thread.currentThread().isInterrupted()
并在检测到中断时让任务 return 让您的任务响应中断。使用 ExecutorService 的 shutdownNow 方法中断当前 运行 任务。 shutdown 方法使执行器停止接收新任务,但让已经提交给执行器的任务 运行 完成。
不要为此子class 线程,您应该扩展 Runnable 或 Callable 以定义提交给 Executor 的任务。 Subclassing Thread 意味着任务分配一个 OS 线程,这是不必要的,因为实际线程已经在线程池中创建。对于此示例,由于您正在计算任务中的数字,因此使用 Callable 可能有意义。
java.util.concurrent中已有一个class就是为这种东西设计的。 API documentation for ExecutorCompletionService.
中给出了找到答案后取消任务的示例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." );
}
}
}
}