我有一个固定大小为12的线程池。现在我有两个实现Runnable的类和每个类的20个对象。我可以提交所有任务,并且线程池将按常规方式完成其工作。
我想做的是制作分隔符。因此,如果我提交这40个任务,则线程池将不会同时处理每个类中的6个以上。所以线程池的行为就像2个较小的大小为6的线程池。是否可以通过java或guava的API进行?
答案 0 :(得分:0)
不用质疑“为什么” - 可以使用信号量来实现,每个信号量都以6的数量创建,每个信号量都将每种类型的任务数量同时划分为6个。
这是一个基本的工作样本:
public class TaskDelimitingTest {
private enum Tasks {TASK1, TASK2};
private static ConcurrentHashMap<Tasks, AtomicInteger> taskObserver = new ConcurrentHashMap<>();
public static class Task implements Runnable {
private static final Random random = new Random(System.currentTimeMillis());
private final Semaphore sem = new Semaphore(6, true);
private final Tasks task;
public Task(Tasks task) {
this.task = task;
}
@Override
public void run() {
try {
taskObserver.get(task).incrementAndGet();
Thread.sleep(random.nextInt(1000));
taskObserver.get(task).decrementAndGet();
sem.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void postToExecution(ExecutorService executor) {
try {
sem.acquire();
executor.execute(this);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class Task1 extends Task {
public Task1() {
super(Tasks.TASK1);
}
}
public static class Task2 extends Task {
public Task2() {
super(Tasks.TASK2);
}
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(12);
Thread t1 = new Thread(() -> {
taskObserver.put(Tasks.TASK1, new AtomicInteger());
IntStream.rangeClosed(1, 100).forEach(i -> {
new Task1().postToExecution(executor);
System.out.println(taskObserver);
});
});
Thread t2 = new Thread(() -> {
taskObserver.put(Tasks.TASK2, new AtomicInteger());
IntStream.rangeClosed(1, 100).forEach(i -> {
new Task2().postToExecution(executor);
System.out.println(taskObserver);
});
});
t1.start();
t2.start();
}
}
在这个例子中,我在两个独立的线程中创建了两个类型中的每一个的100个任务,以便它们可以相互竞争,我还在Thread.sleep
方法中放置run
以便它们模拟不同的执行时间。
该程序的输出是 - 在“预热”阶段
{TASK2=1, TASK1=1}
...
{TASK2=2, TASK1=3}
...
{TASK2=4, TASK1=3}
...
{TASK2=4, TASK1=4}
...
{TASK2=4, TASK1=5}
...
在某个时候游泳池已经饱和,然后就会这样:
{TASK2=6, TASK1=6}
...
因此,只有每种类型的最多6个线程同时执行。