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