Skip to content

Instantly share code, notes, and snippets.

@juliano
Created December 23, 2011 13:09
Show Gist options
  • Save juliano/1514165 to your computer and use it in GitHub Desktop.
Save juliano/1514165 to your computer and use it in GitHub Desktop.
Concurrent list sorter
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
public final class ConcurrentListSorter {
private final ThreadPoolExecutor executor;
private final List<Long> list;
public ConcurrentListSorter(final List<Long> list) {
this.list = list;
executor = new ThreadPoolExecutor(2, 2, 0, SECONDS,
new ArrayBlockingQueue<Runnable>(Integer.MAX_VALUE));
}
public List<Long> sort() throws InterruptedException, ExecutionException {
Future<List<Long>> future1 = executor.submit(new Sorter(firstHalf(list)));
Future<List<Long>> future2 = executor.submit(new Sorter(secondHalf(list)));
return intercalate(future1.get(), future2.get());
}
private List<Long> firstHalf(final List<Long> list) {
int half = list.size() / 2;
return new ArrayList<Long>(list.subList(0, half));
}
private List<Long> secondHalf(final List<Long> list) {
int half = list.size() / 2;
return new ArrayList<Long>(list.subList(half, list.size()));
}
private List<Long> intercalate(final List<Long> firstHalf,
final List<Long> secondHalf) {
ArrayList<Long> intercalatedList = new ArrayList<Long>();
while (hasAnyElementIn(firstHalf, secondHalf)) {
if (firstHalf.isEmpty()) {
intercalatedList.add(secondHalf.remove(0));
} else if (secondHalf.isEmpty()) {
intercalatedList.add(firstHalf.remove(0));
} else {
intercalatedList.add(removeLesserElement(firstHalf, secondHalf));
}
}
return intercalatedList;
}
private boolean hasAnyElementIn(final List<Long> firstHalf,
final List<Long> secondHalf) {
return !(firstHalf.isEmpty() && secondHalf.isEmpty());
}
private Long removeLesserElement(final List<Long> firstHalf,
final List<Long> secondHalf) {
if (firstHalf.get(0) < secondHalf.get(0)) {
return firstHalf.remove(0);
} else {
return secondHalf.remove(0);
}
}
private class Sorter implements Callable<List<Long>> {
private final List<Long> list;
private Sorter(final List<Long> list) {
this.list = list;
}
public List<Long> call() throws Exception {
Collections.sort(list);
return list;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment