001/* 002 * Java Genetic Algorithm Library (jenetics-8.1.0). 003 * Copyright (c) 2007-2024 Franz Wilhelmstötter 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 * Author: 018 * Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com) 019 */ 020package io.jenetics.util; 021 022import static java.util.Objects.requireNonNull; 023 024import java.util.concurrent.Executor; 025import java.util.concurrent.Executors; 026import java.util.concurrent.ForkJoinPool; 027 028/** 029 * Batch executor interface, which is used for evaluating a <em>batch</em> of 030 * runnables. The tasks of a batch are executed concurrently and the 031 * {@link #execute(BaseSeq)} method will return, if all tasks of the batch have 032 * been executed. 033 * 034 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a> 035 * @version 8.0 036 * @since 8.0 037 */ 038@FunctionalInterface 039public interface BatchExecutor { 040 041 /** 042 * Executes the runnables of the {@code batch} concurrently and returns, 043 * when all tasks have been executed. 044 * 045 * @param batch the sequence of runnable to be executed concurrently 046 * @throws NullPointerException if the given {@code batch} is {@code null} 047 */ 048 void execute(final BaseSeq<? extends Runnable> batch); 049 050 /** 051 * Create a batch executor, where the execution is forwarded to the given 052 * {@code executor}. 053 * 054 * @param executor the executor, which is actually executing the tasks 055 * @return a new batch executor 056 * @throws NullPointerException if the given {@code executor} is {@code null} 057 */ 058 static BatchExecutor of(final Executor executor) { 059 requireNonNull(executor); 060 061 if (executor instanceof ForkJoinPool pool) { 062 return new BatchForkJoinPool(pool); 063 } else { 064 return new PartitionBatchExecutor(executor); 065 } 066 } 067 068 /** 069 * Return a batch executor, where each task of a given <em>batch</em> is 070 * executed in its own <em>virtual</em> thread. 071 * 072 * @return a new <em>virtual</em> thread batch executor object 073 */ 074 static BatchExecutor ofVirtualThreads() { 075 return batch -> { 076 try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { 077 batch.forEach(executor::execute); 078 } 079 }; 080 } 081 082}