Java 8固定线程池是否始终创建固定数量的线程?

时间:2017-03-01 03:16:25

标签: java multithreading executorservice

我正在查看Java 8固定线程池的代码。这是一个小样本:

    ExecutorService service = Executors.newFixedThreadPool(100);

    try {

        for (int i = 0; i < 10; ++i) {
            service.submit(() -> "In another thread!");
        }

    } catch (Exception e) {
        // Do nothing
    } finally {
        service.shutdown();
    }

我的问题是(分两部分):

一个。上面的固定线程池对象创建多少个线程? 100?或者只是10?

湾如何查看已创建的线程数?

3 个答案:

答案 0 :(得分:3)

  

上面的固定线程池对象创建了多少个线程? 100?或者只是10?

未指定。所有指定的是永远不会超过100个。

  

如何查看已创建的线程数?

没有API。您可以获得前后总线程数,但这可能很模糊,因为Java有其他原因可以创建线程。

答案 1 :(得分:0)

以下是我在学习ExecutorServiceCallableFuture课程时用作习语的两个简单类。

你可以看到我使用了一个大小为2的线程池,并且有10个我需要处理的项目。基本上,您创建一个线程池,传入实现Callable的类,并使用生成的Future作为处理证明。在给定大小为2的线程池的情况下,一次只能处理两个项目。如果您想查看结果,可以更改值。

Main.java:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        List<Future<String>> lst = new ArrayList<Future<String>>();

        for (int i = 0; i < 10; ++i) {
            Callable<String> callable = new Calling();
            Future<String> future = executorService.submit(callable);
            lst.add(future);
        }

        int futureCount = 0;
        for (Future<String> fut : lst) {
            try {
                futureCount++;
                System.out.println("Processed call() in thread " + fut.get() + ", future number: " + futureCount);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        executorService.shutdown();
        while (!executorService.isTerminated()) {
            // wait, basically
        }

        System.out.println("Finished all threads!");

    }
}

Calling.java

import java.util.concurrent.Callable;

public class Calling implements Callable<String> {

    public Calling() {
    }

    public String call() throws InterruptedException {
        System.out.println("Sleeping thread: " + Thread.currentThread().getName());
        Thread.sleep(2000);
        return Thread.currentThread().getName();
    }

}

答案 2 :(得分:0)

请不要假设执行程序如何在应用程序代码中启动底层线程。只是为了满足你的好奇心:

  

上面的固定线程池对象创建了多少个线程? 100?或者只是10?

完全取决于ThreadFactory使用 - 默认情况下,固定的线程池会懒惰地生成线程。当然,除非另有说明,否则任何后续JDK都可能会发生变化。正如@EJP所说,你可以依赖的唯一不变量就是不会超过100个。

  

如何查看已创建的线程数?

没有办法让线程专用于特定的执行器,但是从JVM内部可以使用Thread#getAllStackTraces获取所有 live 线程的调用堆栈映射。或者使用像VisualVM这样的工具。