java - 等待 Fork 加入池 (Java)

标签 java multithreading threadpool cpu fork-join

我在 java 中使用 Fork 连接池进行多任务处理。现在我遇到了这样一种情况,对于每项任务,我都需要点击一个 url,然后等待 10 分钟,然后再次点击另一个 url 来读取数据。现在的问题是,在那 10 分钟内,我的 CPU 处于空闲状态并且没有启动其他任务(比 fork join pool 中定义的任务多)。

static ForkJoinPool pool = new ForkJoinPool(10);
public static void main(String[] args){
    List<String> list = new ArrayList<>();
    for(int i=1; i<=100; i++){
        list.add("Str"+i);
    }
    final Tasker task = new Tasker(list);
    pool.invoke(task);

public class Tasker extends RecursiveAction{

    private static final long serialVersionUID = 1L;
    List<String> myList;
    public Tasker(List<String> checkersList) {
        super();
        this.myList = checkersList;
    }
    @Override
    protected void compute() {
        if(myList.size()==1){
            System.out.println(myList.get(0) + "start");
            //Date start = new Date();
            try {

                    Thread.sleep(10*60*1000);

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(myList.get(0) + "Finished");
        }
        else{
            List<String> temp = new ArrayList<>();
            temp.add(  myList.get( myList.size()-1 )  );
            myList.remove( myList.size()-1 );

            Tasker left = new Tasker(myList);
            Tasker right = new Tasker(temp);

            left.fork();
            right.compute();
            left.join();
        }
    }

现在我应该怎么做才能让 CPU 挑选所有任务,然后并行等待它们。

最佳答案

不幸的是,ForkJoinPool面对 Thread.sleep() 时效果不佳,因为它是为许多快速完成的短任务而设计的,而不是为长时间阻塞的任务而设计的。

相反,对于您要实现的目标,我建议使用 ScheduledThreadPoolExecutor并将您的任务分为两部分。

import java.util.*;
import java.util.concurrent.*;

public class Main {
    static ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(10);
    public static void main(String[] args){
        for(int i=1; i<=100; i++){
            pool.schedule(new FirstHalf("Str"+i), 0, TimeUnit.NANOSECONDS);
        }
    }
    static class FirstHalf implements Runnable {
        String name;
        public FirstHalf(String name) {
            this.name = name;
        }
        public void run() {
            System.out.println(name + "start");
            pool.schedule(new SecondHalf(name), 10, TimeUnit.MINUTES);
        }
    }
    static class SecondHalf implements Runnable {
        String name;
        public SecondHalf(String name) {
            this.name = name;
        }
        public void run() {
            System.out.println(name + "Finished");
        }
    }
}

如果 Java 提供了一个线程池,允许在 Thread.sleep() 期间释放底层资源(即参与线程池的内核线程),您应该改用它,但是我目前不知道有一个。

关于java - 等待 Fork 加入池 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41276552/

相关文章:

java - JFileChooser 和 Bufferedreader 遇到问题

java - 使用 Bouncy CaSTLe 获取 RSA 公钥剩余部分

java - 在 Java 中声明 boolean 变量的正确方法是什么?

java - Hadoop的Hive/Pig、HDFS和MapReduce的关系

java - 迭代时向 HashSet 添加元素

c# - 为什么我应该更喜欢使用 API 异步函数而不是用 Task.Run 包装同步函数?

javascript - nodejs回调代码已同步

c++ - 如何使用多线程 C++ 在循环中启动多个操作

java - 未捕获异常对 Quartz 的 SimpleThreadPool 线程的影响

c# - OutOfMemory Exception C# 使用线程时