内联线程对象的运行速度比从线程继承的类快得多

nic*_*omp 0 java multithreading

这是一个通过三种方式运行简单计数循环的主管道:

  1. 单线程

  2. 2个线程使用内联代码创建两个不同的Thread对象

  3. 2个线程使用从Thread继承的CountingThread类的实例

package main;

import java.util.ArrayList;

public class Main {

    public static void main(String[] args) {
        demo();
    }
    public static void demo() {

        final long limit = 100_000_000_000L;
        long startTime = System.currenatTimeMillis();
        for (long i = 0; i < limit; i++) {
            // Nothing to see here, just counting
        }
        long endTime = System.currentTimeMillis();
        System.out.println("Single threaded: Total execution time: " + (endTime - startTime) + " milliseconds.");

        // Now try it in two threads. Each thread will perform 1/2 of the counting
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (long i = 0; i < limit/2; i++) {
                    // Nothing to see here, just counting
                }
            }
        });  
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (long i = limit/2; i < limit; i++) {
                    // Nothing to see here, just counting
                }
            }
        });  
        startTime = System.currentTimeMillis();
        t1.start();
        t2.start();
        // Join t1 until it ends, then join t2 until it ends. Note that t1 and t2 are running in parallel with this thread.
        try {t1.join();} catch (InterruptedException e) {}
        try {t2.join();} catch (InterruptedException e) {}
        endTime = System.currentTimeMillis();
        System.out.println("2 threaded using inline code: Total execution time: " + (endTime - startTime) + " milliseconds.");

        // Now try it with 2 instances of the CountingThread class.
        ArrayList<CountingThread> countingThreads = new ArrayList<CountingThread>();
        int numberOfThreads = 2;
        long increment = limit / numberOfThreads;
        for (int i = 0; i < numberOfThreads; i++) {
            long start, end;
            start = i * increment;
            end = start + increment;
            countingThreads.add(new CountingThread(start, end));
        }
        // Launch all the threads to run in parallel
        startTime = System.currentTimeMillis();
        for (int i = 0; i < numberOfThreads; i++) {
            countingThreads.get(i).run();
        }

        // Wait for all the threads to finish
        for (int i = 0; i < numberOfThreads; i++) {
            try {countingThreads.get(i).join();} catch(InterruptedException ex) {}
        }
        endTime = System.currentTimeMillis();
        System.out.println(numberOfThreads + " threaded using classes: Total execution time: " + (endTime - startTime) + " milliseconds.");
    }   
}
Run Code Online (Sandbox Code Playgroud)

这是从Thread继承的类:

package main;

/**
 * Count from one long int up to another long int. Really simple
 *
 */
public class CountingThread extends Thread {

    private long start, end;
    public CountingThread(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    public void run() {
        for(long i = start; i <= end; i++) {

        }
//      System.out.println("Thread counted from " + start + " to " + end);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

Single threaded: Total execution time: 40379 milliseconds.
2 threaded using inline code: Total execution time: 23312 milliseconds.
2 threaded using classes: Total execution time: 40358 milliseconds.
Run Code Online (Sandbox Code Playgroud)

看来方法2和3应该花费大约相同的时间。那是怎么回事?

该机器有4个核心。

Ada*_*ker 6

您犯了一个错误,然后调用#run而不是#start。Run方法在同一线程中执行。

countingThreads.get(i).run();
Run Code Online (Sandbox Code Playgroud)