[英]Write to file in random order from multiple threads
我有20个线程并行运行。 每个调用函数,获取200条记录并写入文件。 我想随机化所有记录。 有什么方法可以使我从一个线程中获取10条记录,然后从下一个线程中获取10条记录,以此类推?
有什么方法可以使我从一个线程中获取10条记录,然后从下一个线程中获取10条记录,以此类推?
如果我正确理解,您的问题是如何协调多个线程的输出,以便每个线程按特定顺序打印其输出。
在这种情况下,我将使用“队列”来协调线程的工作。 类似于票务系统。 如果队列的头部与线程ID /名称相对应,则该线程可以打印其输出(完成后,它将从队列的头部删除其名称)。
一个单独的协调器将决定允许线程以什么顺序打印其输出。
例如:
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.*;
import java.util.stream.IntStream;
/**
*
*/
public class SchedulerExample {
public static final int BATCH_LINES = 3;
public static void main(String[] args) throws InterruptedException {
SchedulerExample schedulerExample = new SchedulerExample();
schedulerExample.doTheWork();
}
private void doTheWork() throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(5);
Queue<String> queue = new ConcurrentLinkedQueue<>();
List<String> allowedWorkersNames = new ArrayList<>();
allowedWorkersNames.add("worker1");
allowedWorkersNames.add("worker2");
allowedWorkersNames.add("worker3");
executorService.submit(new Coordinator(allowedWorkersNames, queue));
executorService.submit(new Worker("worker1", queue, BATCH_LINES));
executorService.submit(new Worker("worker2", queue, BATCH_LINES));
executorService.submit(new Worker("worker3", queue, BATCH_LINES));
Thread.sleep(10000);
System.out.println("ending application");
executorService.shutdownNow();
executorService.awaitTermination(5, TimeUnit.SECONDS);
}
}
/**
* this class decides the order in which workers are allowed to print their outputs
*/
class Coordinator implements Callable<Void> {
private List<String> allowedWorkersNames = new ArrayList<>();
private Queue<String> queue;
public Coordinator(List<String> allowedWorkersNames, Queue<String> queue) {
this.allowedWorkersNames = allowedWorkersNames;
this.queue = queue;
}
@Override
public Void call() throws Exception {
while (true) {
if (queue.size() == 0) {
queue.addAll(allowedWorkersNames);
}
Thread.sleep(1000);
}
}
}
class Worker implements Runnable {
private String name;
private int linesCounter;
private Queue<String> queue;
private int batchLines;
public Worker(String name, Queue<String> queue, int batchLines) {
this.name = name;
this.queue = queue;
this.batchLines = batchLines;
}
@Override
public void run() {
while (true) {
// do some useful work here.
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println(name + "was interrupted");
}
// now this thread is ready to print its output.
String currentHeadOfQueue = queue.peek();
if (currentHeadOfQueue != null && currentHeadOfQueue.compareTo(name) == 0) {
IntStream.rangeClosed(1, batchLines).
forEach(i -> {
linesCounter++;
System.out.println(name + " - line:" + linesCounter);
}
);
queue.remove();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.