为什么我的 JAVA 线程池没有节省时间?

Why my JAVA threadpool is not saving time?

我有这个简单的代码,但它并没有节省时间。 运行时间和使用单线程一样。怎么了?你能帮忙吗?我对此很陌生,如果问题太简单,我希望这个问题不会惹恼您。谢谢!

import java.util.Random;
import java.util.concurrent.Callable;
public class Work implements Callable<int[]>
{
    int id;
    int y;

    public Work(int i)
    {
        id=i;
    }

    public int[] doit(){
        Random rand = new Random();
        y=rand.nextInt(10);
        try {
            Thread.sleep(y*1000);                 //1000 milliseconds is one second.
        } catch(InterruptedException ex) {
            Thread.currentThread().interrupt();
            System.out.println(ex.getMessage());
        }
        int x[] = new int[2];
        x[0]=id;
        x[1]=y;

        return x;
    }


    @Override
    public int[] call() throws Exception
    {
        return doit();
    }
}
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Driver
{

    ArrayList<int[]>  result=new  ArrayList<int[]>() ;
    public Driver()
    {
    }

    public void doCalc(int n)
    {

        for (int i=0; i<n; i++) {
            Work w = new Work(i);
            int[] y = w.doit();


            if (y != null) {
                result.add(y);
            }
        }
        int total=0;
        for (int i=0; i< result.size(); i++) {
            System.out.println("id = " + result.get(i)[0] + "; random number = "+ result.get(i)[1]);
            total+=result.get(i)[1];
        }
        System.out.println("total = " + total);
    }
    public void doCalcThread(int n)
    {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i=0; i<n; i++) {
            Work w = new Work(i);
            Future<int[]> future =executor.submit(w);
            int[] y;
            try
            {
                y = future.get();
                if (y != null) {
                    result.add(y);
                }
            } catch (InterruptedException | ExecutionException e)
            {
                e.printStackTrace();
            }

        }
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");

        int total=0;
        for (int i=0; i< result.size(); i++) {
            System.out.println("id = " + result.get(i)[0] + "; random number = "+ result.get(i)[1]);
            total+=result.get(i)[1];
        }
        System.out.println("total = " + total);
    }
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        Driver dr = new Driver();
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
        cal = Calendar.getInstance();
        System.out.println( "before  " + sdf.format(cal.getTime()) );

        //dr.doCalc(5);
        dr.doCalcThread(5);

        cal = Calendar.getInstance();
        System.out.println( "after  " + sdf.format(cal.getTime()) );
    }
}

future.get(); 是等待计算完成的阻塞操作。所以基本上你在你的循环中一次启动一个线程 - >没有任何并行性。这是错误的代码:

for (int i=0; i<n; i++) {
            Work w = new Work(i);
            Future<int[]> future =executor.submit(w);
            int[] y;
            try
            {
                y = future.get();
                if (y != null) {
                    result.add(y);
                }
            } catch (InterruptedException | ExecutionException e)
            {
                e.printStackTrace();
            }

        }

所以基本上您需要将所有 Future<> 存储在列表中,并且在您提交所有这些之后开始调用它们的 get() 方法。这将允许任务 运行 并行。

就像 Svetlin Zarev 提到的,您的 future.get() 正在阻塞,但是如果您使用的是 java 8,我建议您查看 CompleteableFuture,因为您可以看到所有线程运行,并使用 CompleteableFuture.allOf() 检查它们是否全部完成,并在完成后添加结果