我有一个类在泛型List上执行一些递归合并排序,只要该元素实现Comparable。我试图使代码多线程以提高性能,为此,我有一个静态变量maxThreads
,它保持我创建的线程数不爆炸,我有一个静态变量currentThreads
跟踪我当前运行的线程数。我的currentThreads
变量似乎存在竞争条件,但我还没有找到解决方案来修复它。
import java.util.ArrayList;
import java.util.List;
public class ThreadedMergeSorter<E extends Comparable<? super E>> implements, Runnable
{
private List<E> list;
private List<E> left, right;
private Thread t1, t2;
private static final int maxThreads = 4;
private static AtomicInteger currentThreads = new AtomicInteger(0);
private ThreadedMergeSorter(List<E> list)
{
this.list = list;
}
public ThreadedMergeSorter(){}
/**
* Sorts a List<E> using the merge sorting algorithm
* @param list the list to be merge sorted
* @return
* @throws InterruptedException
*/
public void sort(List<E> list)
{
if(list.size() > 1)
{
left = new ArrayList<E>(list.subList(0, list.size()/2));
right = new ArrayList<E>(list.subList(list.size()/2, list.size()));
list.clear();
if(currentThreads.get() < maxThreads)
{
t1 = new Thread(new ThreadedMergeSorter<E>(left));
t1.start();
currentThreads.incrementAndGet();
}
else sort(left);
if(currentThreads.get() < maxThreads)
{
t2 = new Thread(new ThreadedMergeSorter<E>(right));
t2.start();
currentThreads.incrementAndGet();
}
else sort(right);
try{
if(t1 != null)
{
t1.join();
currentThreads.decrementAndGet();
}
if(t2 != null)
{
t2.join();
currentThreads.decrementAndGet();
}
}catch(InterruptedException e){}
list.addAll(mergeSortedLists(left, right));
}
}
/**
* Merges two previously sorted List<E extends Comparable<E>> into a single List
* @param leftArray a List of previously sorted elements
* @param rightArray a List of previously sorted elements
* @return an new sorted List
*/
private List<E> mergeSortedLists(List<E> leftList, List<E> rightList)
{
ArrayList<E> list = new ArrayList<E>();
while(!leftList.isEmpty() && !rightList.isEmpty())
{
if((leftList.get(0)).compareTo(rightList.get(0)) <= 0)
list.add(leftList.remove(0));
else
list.add(rightList.remove(0));
}
if(!leftList.isEmpty())
list.addAll(leftList);
if(!rightList.isEmpty())
list.addAll(rightList);
return list;
}
@Override
public void run()
{
sort(this.list);
}
}
问题出在sort(List<E> list)
语句if
语句和try catch
块中。
答案 0 :(得分:3)
首先,你没有并行运行任何东西。线程以start()
启动,而不是run()
,它只是在当前线程上调用run
方法。
其次,如果您要更新共享变量,请尝试将它们声明为AtomicInteger
:
private static AtomicInteger currentThreads = new AtomicInteger(0);
然后使用这些方法以原子方式递增/递减:
currentThreads.incrementAndGet();
currentThreads.decrementAndGet();
答案 1 :(得分:2)
不要不断创建,终止和销毁线程。不要试图微观管理线程 - 正如你所发现的那样,它非常困难且容易出错。
如果你想断开合并排序,(并且这不是一个坏主意:),请查看ThreadPoolExecutor和CountDownLatch。
答案 2 :(得分:0)
如果您使用的是Java 7,我建议您使用新的Fork/Join,并使用AtomicReferenceArray<E>
代替List
,这样您就可以在线程中进行排序 - 安全的方式。
答案 3 :(得分:0)
另一个解决方案(假设您运行的是Java 5及更新版本)可以将currentThreads
声明为易变类成员:
private static volatile int currentThreads = 0;
您可以详细了解volatile
关键字here。