1
我有一个固定大小的线程池12.现在我有两个类实现Runnable和每个类的20个对象。我可以提交所有任务,并且线程池将按常规执行其任务。在两个类之间共享一个线程池
我想要做的是做一个分隔符。因此,如果我提交了这40个任务,线程池将不会同时处理每个类的6个以上。因此,线程池的行为就像2个较小的6线程池。可以通过java或番石榴的API吗?
我有一个固定大小的线程池12.现在我有两个类实现Runnable和每个类的20个对象。我可以提交所有任务,并且线程池将按常规执行其任务。在两个类之间共享一个线程池
我想要做的是做一个分隔符。因此,如果我提交了这40个任务,线程池将不会同时处理每个类的6个以上。因此,线程池的行为就像2个较小的6线程池。可以通过java或番石榴的API吗?
不用质疑“为什么” - 它可以通过使用信号量来实现,每个信号量的计数为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
方法中,以便它们模拟不同的执行时间。
这个PROGRAMM的输出是 - 在“热身”阶段
{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个线程正在同时执行。
是否可以创建两个大小为6的池? – Fildor
如果我正确理解你的问题,我想你想知道线程池中有多少个活动线程,然后分隔它们,试试[''ThreadPoolExecutor.getActiveCount();'](http://docs.oracle.org/ .com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html#getActiveCount%28%29) – px06
@ px06如果您知道有关问题中所述要求的活动计数,您赢得了什么? – Fildor