public void generaFactura(long idCliente) {
//proceso para generar la factura...
}
//...
//en algún método
List<Long> listaIdClientes = obtenerIdClientesPorFacturar();
//Iniciando pool de hilos
int cantidadHilos = ... ; //cantidad de hilos en el pool
ExecutorService executor = Executors.newFixedThreadPool(cantidadHilos);
//dejando tareas en el pool de hilos
for (final Long idCliente : listaIdClientes) {
executor.execute( () -> generaFactura(idCliente) );
}
//dejar de admitir tareas en el pool de hilos
executor.shutdown();
//el código de acá abajo es opcional
//indica que se debe esperar a que todas las tareas en el
//pool de hilos deben terminar su ejecución
//y que el hilo en ejecución esperará esto
while (!executor.isTerminated() ) { }
难道是这样我使用更多的内核而不是一个而不是一个来运行主线程吗?
在 Java 的情况下,这取决于。当您打开一个线程时,Java 所做的就是将操作委托给操作系统。因此,在这种情况下使用一个或多个内核将取决于操作系统而不是 Java。这意味着在 Linux 上使用 N 个线程用 Java 编写的应用程序可能比在 Windows 上运行它的性能更好(或者可能更差)。此外,线程的执行与您提到的硬件相关联。因此,即使您拥有相同的操作系统,例如 CentOS 6.5(一个 linux 发行版),由于它们拥有的硬件,计算机之间的性能也会有所不同:内核数量、缓存、内存等。
从标题:
线程的想法是同时完成工作。一个例子是:想象你必须粉刷一个有四面墙的房间。如果你只有一个油漆工在 1 小时内粉刷 1 面墙,那么粉刷房间需要 4 个小时。如果您需要加快这项工作,您可以再雇用一名油漆工,房间将在 2 小时内完成粉刷,但您需要额外支付油漆工费用。线程也会发生同样的事情:您可以获得更高的速度,但您将付出额外的代价来获得该速度,在这种情况下,它需要支付额外的处理才能同时运行两个(或更多)进程。对于当前在微处理器中具有至少两个内核的计算机和设备的时代,这不是什么大问题。但请记住,有些进程无法使用线程进行优化。
从文中:
从上面的答案来看,这取决于过程的类型。有些事情无法通过线程进行优化,例如磁盘访问或通过网络访问,这些都是缓慢的过程。但是,有些流程可以使用线程进行优化,例如为一组客户端生成发票:您可以有一个方法
generaFactura(long idCliente)
,有一个线程池并将任务发送到池中,以便并行生成发票(类似于粉刷房间的墙壁)。这在代码中将表示如下,使用
ExecutorService
(因为最好使用管理线程的框架而不是必须手动管理它们):在 Java 的情况下,这取决于。当您打开一个线程时,Java 所做的就是将操作委托给操作系统。因此,在这种情况下使用一个或多个内核将取决于操作系统而不是 Java。这意味着在 Linux 上使用 N 个线程用 Java 编写的应用程序可能比在 Windows 上运行它的性能更好(或者可能更差)。此外,线程的执行与您提到的硬件相关联。因此,即使您拥有相同的操作系统,例如 CentOS 6.5(一个 linux 发行版),由于它们拥有的硬件,计算机之间的性能也会有所不同:内核数量、缓存、内存等。
如上面的代码示例所示,要使用的线程数应取决于对正在执行的任务进行基准测试,并根据要执行的环境选择哪个是最佳值。没有完美的公式或计算。
除此之外,您还可以在其他线程中打开一个或多个线程。这方面的一个示例是创建 Web 应用程序时。对服务器的每个请求都在一个线程中完成,如果在请求进程中打开一个线程,那么您就是在另一个线程中打开一个线程。这不是问题,当前操作系统完全支持它。
简而言之:仅在确实需要时才使用线程。并且永远记得在使用线程之前和之后对你的进程进行基准测试,这样你就可以评估为使用线程支付的成本是否值得花时间。
当然你是对的,从广义上讲,如果你的进程是顺序执行的,显然比它们都并行执行(并发)要花费更长的时间。如果它们并行完成,您的系统在运行时将具有更高的效率。
我对此进行评论,假设您的进程是在线程中执行的候选者,例如异步任务,您必须小心,因为在线程中执行时可能会导致问题的进程或任务。
确切地说,当执行更多任务时,这些任务会被分配(取决于硬件和操作系统)以在内核中进行处理。
回顾一下线程的一些属性会很有趣:
synchronized
,则只有调用线程可以访问 Object 实例,任何其他尝试访问同一实例的线程都必须等待。ThreadGroup
,在 Java 中实现线程池。