私のテストCyclicBarrierのコード

3011 ワード

package cyclicBarrier;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {

	public static void main(String[] args) {
		Project project = new Project(
			new int[][]{
				{1,2,3},
				{3,2,1},
				{4,3,1},
			}
		);
		project.beginProject();
	}

}

//  , workDay 
class Work {
	private int workDay;
	public Work(int workDay) {
		this.workDay = workDay;
	}
	public void doWork() throws InterruptedException {
		Thread.sleep(workDay*1000);
	}
}

//  , 
class OneLineWorkGroup {
	private LinkedList<Work> workList = new LinkedList<Work>();
	public OneLineWorkGroup(int[] workDayList) {
		for (int n : workDayList)
			workList.add(new Work(n));
	}
	public void startWorkByIndex(int n) throws InterruptedException {
		if (n<0 || n>=workList.size())
			throw new IllegalArgumentException("work index lager than the max index");
		workList.get(n).doWork();
	}
	public int getWorkListSize() {
		return workList.size();
	}
}

//  , 。
//  。 n , n-1 , 。
class Project {
	private OneLineWorkGroup[] syncWorkGroups;
	public Project(int[][] workDays) {
		final int groupCount = workDays.length;
		syncWorkGroups = new OneLineWorkGroup[groupCount];
		for (int n=0; n<groupCount; ++n) {
			int[] oneLineDays = workDays[n];
			syncWorkGroups[n] = new OneLineWorkGroup(oneLineDays);
		}
	}
	public void beginProject() {
		int workCount = syncWorkGroups.length;
		final CyclicBarrier cyclicBarrier = new CyclicBarrier(workCount);
		ExecutorService exe = Executors.newFixedThreadPool(workCount);
		List<Future<?>> futureList = new ArrayList<Future<?>>(workCount);
		for (int n=0; n<workCount; ++n) {
			final int groupIndex = n;
			Future<?> future = exe.submit(new Runnable() {
				@Override
				public void run() {
					OneLineWorkGroup oneLineWorkGroup = syncWorkGroups[groupIndex];
					int workListSize = oneLineWorkGroup.getWorkListSize();
					for (int workIndex=0; workIndex<workListSize; ++workIndex) {
						try {
							oneLineWorkGroup.startWorkByIndex(workIndex);
							System.out.println(String.format("finished: groupIndex==%d, workIndex==%d", groupIndex, workIndex));
							cyclicBarrier.await();
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (BrokenBarrierException e) {
							e.printStackTrace();
						}
					}
				}
			});
			futureList.add(future);
		}
		for (Future<?> future : futureList) {
			Object object;
			try {
				object = future.get();
				System.out.println(object);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		exe.shutdown();
	}
}