Java多线程与单线程性能对比

执行相同的任务量时,多线程是否比单线程要快?如果是,要快上多少?下面是一个测试程序:

MultiThreadsPerformanceTest.java

public class MultiThreadsPerformanceTest {
    public static void main(String[] args) throws Exception {
        int nThreads = 10;
        if (args.length > 0) {
            nThreads = Integer.parseInt(args[0]);
        }
        
        Action myAction = new MyAction();
        
        // nThreads个线程,每个线程执行单位任务
        Thread[] multiThreads = new Thread[nThreads];
        for (int i = 0; i < multiThreads.length; i++) {
            multiThreads[i] = new Thread(new ActionNTimes(myAction, 1));
        }
        ThreadsTimer tt1 = new ThreadsTimer(multiThreads);
        tt1.start();
        
        // 单个线程执行nThreads单位的任务
        Thread[] singleThread = new Thread[1];
        for (int i = 0; i < singleThread.length; i++) {
            singleThread[i] = new Thread(new ActionNTimes(myAction, nThreads));
        }
        ThreadsTimer tt2 = new ThreadsTimer(singleThread);
        tt2.start();
        
        System.out.format("多线程耗时%dms,单线程耗时%dms%n", tt1.getDuration(), tt2.getDuration());
        
        
    }
    
    private static class MyAction implements Action {
        public void act() {
            for (int i = 0; i < 100000; i++) {
                double d = Math.sqrt(i);
            }
        }
    }
    
    private static class ActionNTimes implements Runnable {
        Action action;
        int times;
        
        public ActionNTimes(Action action, int times) {
            this.action = action;
            this.times = times;
        }
        
        public void run() {
            for (int i = 0; i < times; i++) {
                action.act();
            }
        }
    }
}

ThreadsTimer.java

import java.util.*;

/*
 * ThreadsTimer用于统计一组线程从启动到结束的时间间隔
 */
public class ThreadsTimer {
    private Thread[] threads; // 线程们
    private long duration; // 运行时间
    
    public ThreadsTimer(Thread[] threads) {
        this.threads = threads;
    }
    
    public long getDuration() {
        return duration;
    }
    
    /*
     * 启动所有线程并开始计时。方法返回时,所有线程都已结束,且时间统计已完成。
     */
    public void start() throws InterruptedException {
        long start = System.currentTimeMillis();
        
        for (Thread thread:threads) {
            thread.start();
        }
        
        join();
        
        duration = System.currentTimeMillis() - start;    
    }
    
    /*
     * 当前线程频繁让出CPU时间片给待统计的线程,直到所有待统计的线程结束,从而使得统计更加准确
     */
    private void join() throws InterruptedException {
        ArrayList liveThreads = new ArrayList<>(threads.length);
        for (Thread thread:threads) {
            if (thread.isAlive()) {
                liveThreads.add(thread);
            }
        }
        
        while (!liveThreads.isEmpty()) {
            // 随机选择一个存活线程,将时间片让给它
            Random random = new Random();
            int i = random.nextInt(liveThreads.size());
            Thread t = liveThreads.get(i);
            
            if (t.isAlive()) {
                t.join(100);
            } else {
                liveThreads.remove(i);
            }
        }
    }
    
}

Action.java

public interface Action {
    public void act();
}

程序的几次运行结果如下:

D:\Java\多线程性能测试>java MultiThreadsPerformanceTest 10
多线程耗时5ms,单线程耗时10ms

D:\Java\多线程性能测试>java MultiThreadsPerformanceTest 100
多线程耗时31ms,单线程耗时92ms

D:\Java\多线程性能测试>java MultiThreadsPerformanceTest 1000
多线程耗时243ms,单线程耗时921ms


可以看到,开的线程越多,性能差距越明显。当开1000个线程时,多线程的性能几乎是单线程的4倍,而我的处理器正好也是4核,要说这只是巧合,我是万万不信的。

你可能感兴趣的:(JavaSE)