Java 什么';我的多线程程序有什么问题?
我正试图在Java上编写一个多线程版本的shell sort 这是单线程版本的代码Java 什么';我的多线程程序有什么问题?,java,multithreading,Java,Multithreading,我正试图在Java上编写一个多线程版本的shell sort 这是单线程版本的代码 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 < 1000
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();
}
}
}
}
import java.util.*;
导入java.util.Scanner.*;
课堂测试
{
公共静态void main(字符串[]args)
{
double[]列表=新的double[10000];
对于(int i=0;i<10000;i++)
列表[i]=10000-i;
long startTime=System.currentTimeMillis();
shellSort(列表);
int elapsedTime=(int)(System.currentTimeMillis()-startTime);
System.out.println(“Time=“+elapsedTime”);
用于(双i:列表)
System.out.print(i+“”);
}
公共静态void外壳排序(双[]列表)
{
int i,增量;
int[]k={1,4,13,40,121,364,1093,3280,9841,29524,88573,265720,797161,2391484};
对于(i=k.length-1;k[i]>list.length;i--);
对于(i--;i>=0;i--)
{
增量=k[i];
整数上限=2*增量;
对于(整数计数=增量;计数<上限;计数++)
插入排序(列表、增量、计数);
}
}
公共静态void insertionSort(双[]列表,整数增量,整数位置)
{
for(int top=position;top=0&&item
这是多线程版本的代码
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();
}
}
}
}
import java.util.*;
导入java.util.Scanner.*;
类MT扩展线程
{
双[]列表;
int增量,位置;
MT(双[]a,整数b,整数c)
{
列表=a;
增量=b;
位置=c;
}
公开募捐
{
for(int top=position;top=0&&itemlist.length;i--);
对于(i--;i>=0;i--)
{
增量=k[i];
整数上限=2*增量;
对于(整数计数=增量;计数<上限;计数+=2)
{
新MT(列表、增量、计数).start();
新MT(列表、增量、计数+1).start();
}
}
}
}
多线程版本比单线程版本花费的时间要长得多。两者都提供了正确的输出,多线程版本使用了我的3个内核,而不是预期的2个。是什么原因导致我的多线程程序速度减慢?我能想到的唯一一件事是,每当我调用MT类时,我都会创建一个包含数字的数组
谢谢。创建一个新的
线程有相当大的开销。看起来您可能正在嵌套的for
语句中创建一组线程,其中包含
new MT(list, increment, count).start();
考虑使用a来减少初始化开销。以下是我用于创建多线程处理循环的模式。我已经用过几十次了,非常成功。模式总是一样的:谢尔
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);
}
}
公共类测试{
//任务封装了要完成的工作
公共静态类TestTask扩展了FutureTask{
公共测试任务(测试工作者){
超级(工人);
}
}
//工作人员完成工作,可调用扩展
公共静态类TestWorker扩展了可调用{
公共双[]未分类列表;
public Double[]call()引发异常{
//完成工作,返回双倍数组。。。
Double[]结果=shellSort(未排序列表);
//做其他事情
返回结果;
}
}
公共静态void main(字符串[]args){
BlockingQueue=新建LinkedBlockingDeque();
//使用由15个线程组成的固定大小的线程池
ThreadPoolExecutor tpe=新的ThreadPoolExecutor(15,15,1000L,TimeUnit.SECONDS,queue);
CopyOnWriteArrayList allTasks=新建CopyOnWriteArrayList();
对于(int i=0;i<10000;i++){
TestWorker=新的TestWorker();
worker.unsortedList=//要排序的列表。。。
TestTask任务=新的TestTask(工作者);
添加(任务);
执行(任务);
}
做{
//基本上只是循环,直到所有任务都完成。
//也许加入一条线索会很好。也在这里睡觉(10000)
for(TestTask任务:所有任务){
if(task.isDone()){
//如果任务已完成,请将其从arraylist中删除
//记住在获得结果之前删除任务
所有任务。删除(任务);