use*_*972 9 java concurrency multithreading executor
我写了一些Java代码来了解有关Executor框架的更多信息.
具体来说,我编写了代码来验证Collatz假设 - 这表示如果迭代地将以下函数应用于任何整数,最终会得到1:
f(n)=((n%2)== 0)?n/2:3*n + 1
CH仍然未经证实,我认为这是了解Executor的好方法.为每个线程分配一个范围[l,u]的整数来检查.
具体来说,我的程序有3个参数--N(我要检查CH的数字),RANGESIZE(线程必须处理的间隔的长度)和NTHREAD,线程池的大小.
我的代码工作正常,但我看到的速度比我预期的要少得多 - 当我从1线程变为4线程时,大约为30%.
我的逻辑是计算完全是CPU绑定的,每个子任务(检查固定大小范围的CH)大致需要相同的时间.
有谁有想法为什么我没有看到速度增加3到4倍?
如果你可以在增加线程数量(以及机器,JVM和操作系统)时报告你的运行时,这也是很好的.
细节
运行时:
java -d64 -server -cp.Collatz 10000000 1000000 4 => 4个线程,需要28412毫秒
java -d64 -server -cp.Collatz 10000000 1000000 1 => 1个线程,需要38286毫秒
处理器:
Quadcore Intel Q6600,2.4GHZ,4GB.机器已卸载.
Java的:
java版"1.6.0_15"Java(TM)SE运行时环境(版本1.6.0_15-b03)Java HotSpot(TM)64位服务器VM(版本14.1-b02,混合模式)
OS:
Linux quad0 2.6.26-2-amd64#1 SMP Tue Mar 9 22:29:32 UTC 2010 x86_64 GNU/Linux
代码:(我无法获取要发布的代码,我认为对于SO要求来说太长了,可以在Google Docs上找到源代码
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyRunnable implements Runnable {
public int lower;
public int upper;
MyRunnable(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
@Override
public void run() {
for (int i = lower ; i <= upper; i++ ) {
Collatz.check(i);
}
System.out.println("(" + lower + "," + upper + ")" );
}
}
public class Collatz {
public static boolean check( BigInteger X ) {
if (X.equals( BigInteger.ONE ) ) {
return true;
} else if ( X.getLowestSetBit() == 1 ) {
// odd
BigInteger Y = (new BigInteger("3")).multiply(X).add(BigInteger.ONE);
return check(Y);
} else {
BigInteger Z = X.shiftRight(1); // fast divide by 2
return check(Z);
}
}
public static boolean check( int x ) {
BigInteger X = new BigInteger( new Integer(x).toString() );
return check(X);
}
static int N = 10000000;
static int RANGESIZE = 1000000;
static int NTHREADS = 4;
static void parseArgs( String [] args ) {
if ( args.length >= 1 ) {
N = Integer.parseInt(args[0]);
}
if ( args.length >= 2 ) {
RANGESIZE = Integer.parseInt(args[1]);
}
if ( args.length >= 3 ) {
NTHREADS = Integer.parseInt(args[2]);
}
}
public static void maintest(String [] args ) {
System.out.println("check(1): " + check(1));
System.out.println("check(3): " + check(3));
System.out.println("check(8): " + check(8));
parseArgs(args);
}
public static void main(String [] args) {
long lDateTime = new Date().getTime();
parseArgs( args );
List<Thread> threads = new ArrayList<Thread>();
ExecutorService executor = Executors.newFixedThreadPool( NTHREADS );
for( int i = 0 ; i < (N/RANGESIZE); i++) {
Runnable worker = new MyRunnable( i*RANGESIZE+1, (i+1)*RANGESIZE );
executor.execute( worker );
}
executor.shutdown();
while (!executor.isTerminated() ) {
}
System.out.println("Finished all threads");
long fDateTime = new Date().getTime();
System.out.println("time in milliseconds for checking to " + N + " is " +
(fDateTime - lDateTime ) +
" (" + N/(fDateTime - lDateTime ) + " per ms)" );
}
}
Run Code Online (Sandbox Code Playgroud)
axt*_*avt 11
忙碌的等待可能是一个问题:
while (!executor.isTerminated() ) {
}
Run Code Online (Sandbox Code Playgroud)
你可以awaitTermination()改用:
while (!executor.awaitTermination(1, TimeUnit.SECONDS)) {}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
801 次 |
| 最近记录: |