Ich habe hier mal versucht, wie es aussehen kann, etwas asynchron zu verarbeiten. Es wird alle 3 Sekunden ein zufälliger String in die Queue eingefügt. Ein anderer Thread verarbeitet den Inhalt der Queue sobald er dazu in der Lage ist. Im Prinzip könnte das auch mit mehreren Threads durchgeführt werden. Die Verarbeitung endet wenn die Queue leer ist (nur für mein Beispiel) - das muss man nicht so machen. Nach einer Minute wird die Queue nicht mehr weiter befüllt, damit das Programm irgendwann zu Ende kommt.
[CODE=java]
import java.time.Duration;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
public class Main {
// Start writing to the queue immediately, every 3 seconds
private static final int DELAY = 3;
private final BlockingQueue<String> queue = new LinkedBlockingQueue<>();
private String createRandomString() {
final int leftLimit = 97; // letter 'a'
final int rightLimit = 122; // letter 'z'
final int targetStringLength = 10;
final Random random = ThreadLocalRandom.current();
final StringBuilder buffer = new StringBuilder(targetStringLength);
for (int i = 0; i < targetStringLength; i++) {
final int randomLimitedInt = leftLimit + (int) (random.nextFloat() * (rightLimit - leftLimit + 1));
buffer.append((char) randomLimitedInt);
}
return buffer.toString();
}
private void enqueue(final long shutdownAfter) {
final ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
// executes method #generate every #DELAY seconds
final Future<?> future = pool.scheduleAtFixedRate(this::generate , DELAY, DELAY, TimeUnit.SECONDS);
// stopping after #shutdownAfter minutes else run forever
if (shutdownAfter > 0L) {
pool.schedule(
() -> {
future.cancel(true);
pool.shutdown();
},
shutdownAfter, TimeUnit.MINUTES);
}
}
// generate random string an add to queue
private void generate() {
final String generatedString = createRandomString();
System.out.format("🚩 create random string and put to queue: %s%n", generatedString);
queue.add(generatedString);
}
// new thread processing queue's content
private void dequeue() {
Executors.newSingleThreadExecutor().execute(this::process);
}
private void process() {
do {
try {
final String element = queue.take();
System.out.format("🏁 get string from queue if available and process in long running task: %s%n", element);
doLongRunningStuff(element);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
}
} while (!queue.isEmpty()); // stopping the task when #queue is empty
}
private void doLongRunningStuff(final String element) throws InterruptedException {
Objects.requireNonNull(element);
Thread.sleep(Duration.ofSeconds(DELAY * DELAY)); // simulate long running task
}
public static void main(final String[] args) throws InterruptedException {
final Main main = new Main();
main.enqueue(1); // stopping after 1 minute but program ends, when queue is empty
main.dequeue();
System.out.println("Wait ...");
}
}
[/CODE]