java - 内联 Thread 对象的运行速度比从 Thread 继承的类快得多

标签 java multithreading

这是一个以三种方式运行简单计数循环的 main:

  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.");
    }   
}

这是继承自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);
    }
}

这是输出:

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.

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

该机器有 4 个核心。

最佳答案

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

countingThreads.get(i).run();

关于java - 内联 Thread 对象的运行速度比从 Thread 继承的类快得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56723942/

相关文章:

java - Android 中用于自定义布局的 ArrayAdapter?

java - 如何在不使用标签的情况下重写java代码?

java.lang.IllegalStateException : The path to the driver executable must be set by the webdriver. chrome.driver 系统属性

java - Java 中数组的微妙行为

c - 冗余 __thread 和 omp threadlocal 声明

java - 在多线程中使用wait()和notify()

c++ - 如何以与平台无关的方式终止卡在阻塞 IO 上的线程?

c# - .Net Garbage 会收集一个未被引用但有一个正在工作的线程的对象吗?

java - 在 java 的同步方法或 block 中使用时的静态成员

java - 运行时Exec改变路径