Looking for java Keywords? Try Ask4Keywords

Java Language Pitfall - создание темы относительно дорого


пример

Рассмотрим эти два микро-теста:

Первый тест просто создает, запускает и соединяет потоки. Runnable потока не работает.

public class ThreadTest {
    public static void main(String[] args) throws Exception {
        while (true) {
            long start = System.nanoTime();
            for (int i = 0; i < 100_000; i++) {
                Thread t = new Thread(new Runnable() {
                        public void run() {
                }});
                t.start();
                t.join();
            }
            long end = System.nanoTime();
            System.out.println((end - start) / 100_000.0);
        }
    }
}

$ java ThreadTest 
34627.91355
33596.66021
33661.19084
33699.44895
33603.097
33759.3928
33671.5719
33619.46809
33679.92508
33500.32862
33409.70188
33475.70541
33925.87848
33672.89529
^C

На типичном современном ПК под управлением Linux с 64-битным Java 8 u101 этот тест показывает среднее время, затрачиваемое на создание, запуск и объединение потоков между 33,6 и 33,9 микросекундами.

Второй контрольный показатель эквивалентен первому, но с использованием ExecutorService для отправки задач и Future для рандеву с окончанием задачи.

import java.util.concurrent.*;

public class ExecutorTest {
    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        while (true) {
            long start = System.nanoTime();
            for (int i = 0; i < 100_000; i++) {
                Future<?> future = exec.submit(new Runnable() {
                    public void run() {
                    }
                });
                future.get();
            }
            long end = System.nanoTime();
            System.out.println((end - start) / 100_000.0);
        }
    }
}

$ java ExecutorTest
6714.66053
5418.24901
5571.65213
5307.83651
5294.44132
5370.69978
5291.83493
5386.23932
5384.06842
5293.14126
5445.17405
5389.70685
^C

Как вы можете видеть, средние значения составляют от 5,3 до 5,6 микросекунд.

Хотя фактическое время будет зависеть от множества факторов, разница между этими двумя результатами значительна. Очевидно, что быстрее использовать пул потоков, чтобы перерабатывать потоки, чем создавать новые потоки.