我的多线程程序出了什么问题?

时间:2011-11-20 04:16:30

标签: java multithreading

我正在尝试在Java上编写一个multhithreaded版本的shell排序

这是单线程版本的代码

    import java.util.*;
import java.util.Scanner.*;

class Test
{           
    public static void main (String [] args)
    {
        double [] list = new double [10000];
        for (int i = 0; i < 10000; i++)
            list[i] = 10000 - i;
        long startTime = System.currentTimeMillis();
        shellSort(list);
        int elapsedTime = (int) (System.currentTimeMillis() - startTime);
        System.out.println ("Time = " + elapsedTime);
        for (double i : list)
            System.out.print (i + " ");

    }
    public static void shellSort(double [] list)
    {
        int i, increment;
        int [] k = {1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484};
        for (i = k.length - 1; k[i] > list.length; i--);
        for (i--; i >= 0; i--)
        {
            increment = k[i];
            int upper = 2 * increment;
            for (int count = increment; count < upper; count++)
                insertionSort(list, increment, count);
        }
    }
    public static void insertionSort(double [] list, int increment, int position)
    {
        for (int top = position; top < list.length;)
        {
            double item = list[top];
            int i = top;
            while (i - increment >= 0 && item < list[i - increment])
            {
                list[i] = list[i - increment];
                i -= increment;
            }
            list[i] = item;
            top += increment;
        }
    }

}

这是多线程版本的代码

    import java.util.*;
import java.util.Scanner.*;

class MT extends Thread
    {
        double[] list;
        int increment, position;
        MT (double [] a, int b, int c)
        {
            list = a;
            increment = b;
            position = c;
        }
        public void run()
        {
            for (int top = position; top < list.length;)
            {
                double item = list[top];
                int i = top;
                while (i - increment >= 0 && item < list[i - increment])
                {
                    list[i] = list[i - increment];
                    i -= increment;
                }
                list[i] = item;
                top += increment;
            }
        }
    }


class Test
{
    public static void main (String [] args)
    {
        double [] list = new double [10000];
        for (int i = 0; i < 10000; i++)
            list[i] = 10000 - i;
        long startTime = System.currentTimeMillis();
        shellSort(list);
        int elapsedTime = (int) (System.currentTimeMillis() - startTime);
        System.out.println ("Time = " + elapsedTime);
        for (double i : list)
            System.out.print (i + " ");

    }
    public static void shellSort(double [] list)
    {
        int i, increment;
        int [] k = {1, 4, 13, 40, 121, 364, 1093, 3280, 9841, 29524, 88573, 265720, 797161, 2391484};
        for (i = k.length - 1; k[i] > list.length; i--);
        for (i--; i >= 0; i--)
        {
            increment = k[i];
            int upper = 2 * increment;
            for (int count = increment; count < upper; count+=2)
            {
                new MT(list, increment, count).start();
                new MT(list, increment, count + 1).start();
            }
        }
    }       
}

多线程版本比单线程版本需要更长的时间。两者都提供正确的输出,多线程版本使用我的3个内核而不是预期的2个。我的多线程程序导致这种减速的原因是什么?我唯一能想到的是,每当我调用MT类时,我都在创建包含数字的数组?

感谢。

2 个答案:

答案 0 :(得分:1)

这是我用于创建多线程处理循环的模式。我已经使用了几十次,非常成功。模式总是一样的:shel

public class Test {

    // the Task encapsulates the work to be done
    public static class TestTask extends FutureTask<Doulbe[]> {
         public TestTask(TestWorker worker) {
             super(worker);
         }
    }

    // the worker does the work, extends Callable
    public static class TestWorker extends Callable<Double[]> {
         public Double[] unsortedList;
         public Double[] call() throws Exception {
              // do the work, return the array of Doubles...
              Double[] results = shellSort(unsortedList);
              // do other stuff
              return results;
         }       
    }

    public static void main (String [] args) {

        BlockingQueue<Runnable> queue = new LinkedBlockingDeque<Runnable>();
        // use a constant sized thread pool of 15 threads
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(15, 15, 1000L, TimeUnit.SECONDS, queue);
        CopyOnWriteArrayList<TestTask> allTasks = new CopyOnWriteArrayList<TestTask>();
        for (int i = 0; i < 10000; i++ ) {
            TestWorker worker = new TestWorker();
            worker.unsortedList = // your list to be sorted...
            TestTask task = new TestTask(worker);
            allTasks.add(task);
            tpe.execute(task);
        }

        do {
            // basically just loop until all tasks are finished.
            // might be good to throw in a Thread.sleep(10000) here too
            for ( TestTask task : allTasks ) {
                if ( task.isDone() ) {
                    // if the task is done, remove it from the arraylist
                    // remember to remove the task before getting the results
                    allTasks.remove(task);
                    try {
                       Double[] sortedList = task.get();
                       // do something with the output.
                    } catch ( Exception e ) {
                        LOGGER.error("Task threw exception...", e);
                    }
                }
            }
        } while ( allTasks.size() > 0);



    }

}

答案 1 :(得分:0)

创建新Thread会产生相当大的开销。看起来您可能在包含

的嵌套for语句中创建了一堆线程
new MT(list, increment, count).start();

考虑使用thread pool来减少初始化开销。