我的多线程程序有什么问题? [英] What's wrong with my multithreaded program?

查看:76
本文介绍了我的多线程程序有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Java 上编写多线程版本的 shell 排序

I'm trying to write a multhithreaded version of shell sort on Java

这是单线程版本的代码

    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 类时,我都会创建包含数字的数组?

The multithreaded version takes significantly longer than the single threaded version. Both gives the correct output, and the multithreaded version is using 3 of my cores rather than 2 as intended. What is causing this slowdown with my multithreaded program? The only thing I can think of is I'm creating the array containing the numbers whenever I call the MT class?

谢谢.

推荐答案

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

Here is the pattern I use for creating multi-threaded processing loops. I've used this dozens of times, very successfully. The pattern is always the same: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);



    }

}

这篇关于我的多线程程序有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆