在两个类

时间:2016-08-09 07:42:04

标签: java multithreading

我有一个固定大小为12的线程池。现在我有两个实现Runnable的类和每个类的20个对象。我可以提交所有任务,并且线程池将按常规方式完成其工作。

我想做的是制作分隔符。因此,如果我提交这40个任务,则线程池将不会同时处理每个类中的6个以上。所以线程池的行为就像2个较小的大小为6的线程池。是否可以通过java或guava的API进行?

1 个答案:

答案 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个线程同时执行。