tha*_*man 4 java cpu multithreading fork-join threadpool
我在Java中使用Fork联接池进行多任务处理。现在我遇到了一种情况,对于每个任务,我需要点击一个网址,然后等待10分钟,然后再次点击另一个网址以读取数据。现在的问题是,在那10分钟内,我的CPU处于空闲状态,并且没有启动其他任务(比fork联接池中定义的任务更多)。
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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我应该怎么做,以便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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果Java提供了一个线程池,该线程池允许在期间释放基础资源(即,参与线程池的内核线程)Thread.sleep(),则应该改用该线程池,但是我目前不知道该线程池。