Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多线程的并行执行和终止_Java_Multithreading_Concurrency_Parallel Processing - Fatal编程技术网

Java 多线程的并行执行和终止

Java 多线程的并行执行和终止,java,multithreading,concurrency,parallel-processing,Java,Multithreading,Concurrency,Parallel Processing,我有一个简单的应用程序,我在一个类中创建了3个线程来ping 3个不同的网站,并记录了这样做所花费的时间 我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它 JDK的哪个类在这样做时会有帮助?怎么做 ping网站的示例代码: public static boolean pingUrl(final String address) { try { final URL url = new URL("http://" + address); final HttpUR

我有一个简单的应用程序,我在一个类中创建了3个线程来ping 3个不同的网站,并记录了这样做所花费的时间

我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它

JDK的哪个类在这样做时会有帮助?怎么做

ping网站的示例代码:

public static boolean pingUrl(final String address) {

 try {

  final URL url = new URL("http://" + address);

  final HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
  urlConn.setConnectTimeout(1000 * 10); // mTimeout is in seconds

  final long startTime = System.currentTimeMillis();

  urlConn.connect();

  final long endTime = System.currentTimeMillis();

  if (urlConn.getResponseCode() == HttpURLConnection.HTTP_OK) {

   System.out.println("Time (ms) : " + (endTime - startTime));
   System.out.println("Ping to "+address +" was success");

   return true;
  }
 } catch (final MalformedURLException e1) {
  e1.printStackTrace();
 } catch (final IOException e) {
  e.printStackTrace();
 }
 return false;
}
我想可能有用。主要思想是,生成的线程在完成时将一些值写入
BlockingQueue
,并在
InterruptedException

例如:

public void runPing(List<String> urls) {
    Collection<Thread> runningThreads = new ArrayList<>(urls.size());
    final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(urls.size());
    for (int i = 0; i < 3; i++) {
        final String url = urls.get(i);
        Thread t = new Thread(new Runnable() {
            public void run() {
                pingUrl(url);
                queue.add(1);
            }
        });
        runningThreads.add(t);
    }
    try {
        queue.poll(1, TimeUnit.HOURS);
        interruptChilds(runningThreads);
    } catch (Exception e) {
        interruptChilds(runningThreads);
    }
}

private void interruptChilds(Collection<Thread> runningThreads) {
    for (Thread t : runningThreads) {
        t.interrupt();
    }
}
公共无效运行(列出URL){
集合runningThreads=newarraylist(url.size());
final BlockingQueue=new ArrayBlockingQueue(url.size());
对于(int i=0;i<3;i++){
最终字符串url=url.get(i);
线程t=新线程(新的可运行线程(){
公开募捐{
pingUrl(url);
添加(1);
}
});
运行线程。添加(t);
}
试一试{
队列.轮询(1,时间单位.小时);
中断子线程(运行线程);
}捕获(例外e){
中断子线程(运行线程);
}
}
私有void interruptChilds(集合运行线程){
对于(线程t:运行线程){
t、 中断();
}
}
请注意,在中没有处理
中断异常
。应该在您的方法中添加它

我想可能有用。主要思想是,生成的线程在完成时将一些值写入
BlockingQueue
,并在
InterruptedException

例如:

public void runPing(List<String> urls) {
    Collection<Thread> runningThreads = new ArrayList<>(urls.size());
    final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(urls.size());
    for (int i = 0; i < 3; i++) {
        final String url = urls.get(i);
        Thread t = new Thread(new Runnable() {
            public void run() {
                pingUrl(url);
                queue.add(1);
            }
        });
        runningThreads.add(t);
    }
    try {
        queue.poll(1, TimeUnit.HOURS);
        interruptChilds(runningThreads);
    } catch (Exception e) {
        interruptChilds(runningThreads);
    }
}

private void interruptChilds(Collection<Thread> runningThreads) {
    for (Thread t : runningThreads) {
        t.interrupt();
    }
}
公共无效运行(列出URL){
集合runningThreads=newarraylist(url.size());
final BlockingQueue=new ArrayBlockingQueue(url.size());
对于(int i=0;i<3;i++){
最终字符串url=url.get(i);
线程t=新线程(新的可运行线程(){
公开募捐{
pingUrl(url);
添加(1);
}
});
运行线程。添加(t);
}
试一试{
队列.轮询(1,时间单位.小时);
中断子线程(运行线程);
}捕获(例外e){
中断子线程(运行线程);
}
}
私有void interruptChilds(集合运行线程){
对于(线程t:运行线程){
t、 中断();
}
}
请注意,在中没有处理
中断异常
。应该将其添加到您的方法中

我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它

我将使用
ExecutorService
ExecutorCompletionService
组合使用。然后,当第一个任务完成时,从完成服务返回第一个
Future
时,您可以在
ExecutorService
上调用
shutdownow()

这些工具非常好,并展示了如何使用它

// maybe you want 10 threads working on your tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10); 
CompletionService<Result> ecs
     = new ExecutorCompletionService<Result>(threadPool);
for (Callable<Result> task : tasks) {
    // submit your tasks to the completion service, they run in the thread-pool
    ecs.submit(task);
}
// once you get one result
Future<Result> future = ecs.take();
// kill the rest of the tasks
threadPool.shutdownNow();
Result result = future.get();
// probably will need to close the thread connections, see below
// maybe call threadPool.awaitShutdown(...) here to wait for the others to die
在您的情况下,您的任务可能类似于:

public class MyPingTask implements Callable<Boolean> {
    private String address;
    public MyPingTask(String address) {
        this.address = address;
    }
    public Boolean call() throws Exception {
         // obviously the pingUrl code could go right here
         return pingUrl(address);
    }
}
公共类MyPingTask实现可调用{
私有字符串地址;
公共MyPingTask(字符串地址){
this.address=地址;
}
公共布尔调用()引发异常{
//显然pingUrl代码可能就在这里
返回pingUrl(地址);
}
}
下面是相关的课程

我希望通过查看3个线程中的哪个线程首先成功执行并终止其他两个线程来增强它

我将使用
ExecutorService
ExecutorCompletionService
组合使用。然后,当第一个任务完成时,从完成服务返回第一个
Future
时,您可以在
ExecutorService
上调用
shutdownow()

这些工具非常好,并展示了如何使用它

// maybe you want 10 threads working on your tasks
ExecutorService threadPool = Executors.newFixedThreadPool(10); 
CompletionService<Result> ecs
     = new ExecutorCompletionService<Result>(threadPool);
for (Callable<Result> task : tasks) {
    // submit your tasks to the completion service, they run in the thread-pool
    ecs.submit(task);
}
// once you get one result
Future<Result> future = ecs.take();
// kill the rest of the tasks
threadPool.shutdownNow();
Result result = future.get();
// probably will need to close the thread connections, see below
// maybe call threadPool.awaitShutdown(...) here to wait for the others to die
在您的情况下,您的任务可能类似于:

public class MyPingTask implements Callable<Boolean> {
    private String address;
    public MyPingTask(String address) {
        this.address = address;
    }
    public Boolean call() throws Exception {
         // obviously the pingUrl code could go right here
         return pingUrl(address);
    }
}
公共类MyPingTask实现可调用{
私有字符串地址;
公共MyPingTask(字符串地址){
this.address=地址;
}
公共布尔调用()引发异常{
//显然pingUrl代码可能就在这里
返回pingUrl(地址);
}
}

这是和相关的类。

你是如何ping网站的?@vandale添加了示例代码为了正确终止线程,你必须中止
urlConn.connect()
,我认为这是不可能的。你是如何ping网站的?@vandale添加了示例代码为了正确终止线程,您必须中止
urlConn.connect()
,我认为这是不可能的答案!中断问题的可能解决方法:使用自定义
ThreadPoolExecutor
和重写方法
newTaskFor(可调用)
代替
newFixedThreadPool(…)
。它返回一个自定义的
RunnableFuture
,该自定义
RunnableFuture
知道
可调用的
拥有一个
HttpURLConnection
(或
HttpClient
请求对象),并在其
cancel
方法中关闭其连接/中止其请求。从未这样做过@isnot2bad,但听起来它会工作。当然不适合初级线程程序员。回答不错!中断问题的可能解决方法:使用自定义
ThreadPoolExecutor
和重写方法
newTaskFor(可调用)
代替
newFixedThreadPool(…)
。它返回一个自定义的
RunnableFuture
,该自定义
RunnableFuture
知道
可调用的
拥有一个
HttpURLConnection
(或
HttpClient
请求对象),并在其
cancel
方法中关闭其连接/中止其请求。从未这样做过@isnot2bad,但听起来它会工作。当然,对于初级线程程序员来说肯定不是。