package concurrency;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.junit.Test;

public class NonBlockingCounterTest {
	private static final int THREAD_NUMBER = 10;

	@Test
	public void testName() throws Exception {
		List<Future<Integer>> tasks = new ArrayList<Future<Integer>>();
		ExecutorService executor = createExecutor(tasks);
		executor.shutdown();
		waitUntilProcessingFinishes(executor);
		Set<Integer> results = assembleResults(tasks);
		checkIfEqual(tasks, results);
	}

	private ExecutorService createExecutor(List<Future<Integer>> tasks) {
		final NonBlockingCounter counter = new NonBlockingCounter();
		ExecutorService executor = Executors.newFixedThreadPool(THREAD_NUMBER);
		for (int i = 0; i < 500; i++) {
			Callable<Integer> worker = new Callable<Integer>() {
				@Override
				public Integer call() throws Exception {
					int number = counter.increment();
					return number;
				}
			};
			Future<Integer> submit = executor.submit(worker);
			tasks.add(submit);
		}
		return executor;
	}

	private void waitUntilProcessingFinishes(ExecutorService executor) {
		while (!executor.isTerminated()) {
		}
	}

	private Set<Integer> assembleResults(List<Future<Integer>> list) {
		Set<Integer> results = new HashSet<Integer>();
		for (Future<Integer> future : list) {
			try {
				results.add(future.get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		return results;
	}

	private void checkIfEqual(List<Future<Integer>> list, Set<Integer> set) {
		if (list.size() != set.size()) {
			throw new RuntimeException("Double-entries!!!");
		}
	}
}

@@ -60,22 +60,19 @@
 va.util.
-HashSe
+Lis
 t;%0Aimpor
@@ -87,34 +87,27 @@
 til.
-List;%0Aimport java.util.Set
+concurrent.Callable
 ;%0Aim
@@ -125,39 +125,51 @@
 til.concurrent.C
-allable
+opyOnWriteArrayList
 ;%0Aimport java.ut
@@ -666,18 +666,19 @@
 tor);%0A%09%09
-Se
+Lis
 t%3CIntege
@@ -1026,94 +1026,16 @@
 r = 
-new Callable%3CInteger%3E() %7B%0A%09%09%09%09@Override%0A%09%09%09%09public Integer call() throws Exception
+() -%3E
  %7B%0A
-%09
 %09%09%09%09
@@ -1072,17 +1072,16 @@
 ();%0A%09%09%09%09
-%09
 return n
@@ -1091,14 +1091,8 @@
 er;%0A
-%09%09%09%09%7D%0A
 %09%09%09%7D
@@ -1319,18 +1319,19 @@
 private 
-Se
+Lis
 t%3CIntege
@@ -1381,18 +1381,19 @@
 st) %7B%0A%09%09
-Se
+Lis
 t%3CIntege
@@ -1413,14 +1413,27 @@
 new 
-HashSe
+CopyOnWriteArrayLis
 t%3CIn
@@ -1734,12 +1734,14 @@
 list
+1
 , 
-Se
+Lis
 t%3CIn
@@ -1747,19 +1747,21 @@
 nteger%3E 
-set
+list2
 ) %7B%0A%09%09if
@@ -1766,16 +1766,17 @@
 if (list
+1
 .size() 
@@ -1782,11 +1782,13 @@
  != 
-set
+list2
 .siz
@@ -1829,26 +1829,66 @@
 on(%22
-Double-entries!!!%22
+Too many entries: %22 + list1.size() + %22 != %22 + list2.size()
 );%0A%09

Fix test