Можно ли создать высокоприоритетный поток с обычной JVM, который не будет вытеснен никаким другим потоком? - PullRequest
3 голосов
/ 29 марта 2012

Итак, моя цель проста: я хочу создать высокоприоритетный поток в Java без использования RTSJ (виртуальной машины Java реального времени) или какой-либо другой проприетарной JVM.Предположим, вы никогда не создаете мусор, поэтому GC не будет виновником.Давайте предположим, что у меня 4 процессора.Это выполнимо?Если нет, то можно ли подсчитать, сколько раз мой поток был прерван?

@ Grey: я хочу получить как можно больше отклика в реальном времени с минимальной задержкой, без необходимости переходить на RTSJ и специальные ОС

@ sarnold: Вы очень правы.Если вы достигнете этого на уровне JVM, а не на вашей JVM, которая будет прервана ОС, у вас возникнет та же проблема на более низком уровне.Давайте предположим, что можно взломать и / или использовать дистрибутив linux, настроенный не делать этого.

@ StephenC: я уже знаю, что это невозможно.Вот почему я хочу сделать это.:) Если я, по крайней мере, смогу определить приоритет, у меня будет способ измерить мой прогресс.

Ответы [ 3 ]

2 голосов
/ 29 марта 2012

Нет.Стандартная Java не поддерживает это.

Я хочу получить как можно больше отклика в реальном времени с минимальной задержкой, без необходимости обращаться к RTSJ и специальным ОС

"Как можно меньшая задержка »не является поддающимся количественной оценке требованием.

Однако, как я и другие говорили в ответ на ваши многочисленные вопросы в этой области, JavaSE не предназначена для такого рода вещей и не/ не может предоставить никаких гарантий задержки.Действительно, многие аспекты базовых базовых библиотек Java определены , чтобы прояснить, что на стандартных платформах Java нет никаких связанных с производительностью гарантий.

Что касается этого конкретного вопроса, спецификации потоков Java указывают, что приоритеты потоков являются только рекомендательными.Нет никаких гарантий, что поток с более высоким приоритетом не будет вытеснен потоком с более низким приоритетом.Фактические политики планирования и переключения потоков реализуются операционной системой хоста и находятся вне контроля Java.

Давайте предположим, что возможно взломать и / или использовать дистрибутив linux, настроенный для этого.

Если вы делаете это предположение, вы можете просто взломать операционную систему, чтобы заставить планировщик потоков и т. Д. Вести себя так, как вы хотите ... предполагая, что это технически осуществимо.Но также имейте в виду, что взлом на этом уровне может привести к непредвиденным проблемам для приложений (таких как JVM), которые не предназначены для работы (например) с не выгружаемыми потоками, мешающими запуску GC.

Если я хотя бы смог обнаружить приоритетное действие, у меня будет способ измерить мой прогресс.

Поток Java не может обнаружить, что он был прерван, или что другой поток Java был прерван.Я не думаю, что API нативных потоков уровня ОС, которые использует JVM, поддерживают это.

1 голос
/ 29 марта 2012

Я полагаю, вы ищете это: http://en.wikipedia.org/wiki/Real_time_Java Обычная Java не предоставляет такой возможности.

0 голосов
/ 18 июня 2014

Да, это возможно!Но изолировать ядро ​​процессора, чтобы оно не было заблокировано каким-либо пользователем или процессом ядра , является конфигурацией ОС, не связанной с вашим приложением .После этого вы можете использовать библиотеку сродства потоков, такую ​​как CoralThreads , чтобы закрепить ваш поток на изолированном ядре процессора.Это значительно уменьшает дисперсию.Ниже приведен простой пример кода, чтобы вы поняли:

import com.coralblocks.coralthreads.Affinity;

public class Basics {

    public static void main(String[] args) throws Exception {

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {

                // must be the first thing inside the run method
                Affinity.bind();

                try {

                    while(true) {

                        // do whatever you want here...
                    }

                } finally {

                    // must be the last thing inside the run method
                    Affinity.unbind(); 
                }
            }
        }, "MyPinnedThread");

        System.out.println();
        Affinity.printSituation(); // nothing done yet...

        // assign thread to processor:
        int procToBind = Integer.parseInt(args[0]);
        Affinity.assignToProcessor(procToBind, thread);

        Affinity.printSituation(); // now you see it there...

        // start the thread!
        thread.start();

        Affinity.printSituation(); // now it is running with a pid...
    }
}

Вывод:

$ java -cp coralthreads-all.jar com.coralblocks.coralthreads.sample.Basics 2

CpuInfo: [nChips=1, nCoresPerChip=4, hyper-threading=true, nProcessors=8, procIds=0,1,2,3,4,5,6,7]

Chip-0:
    Core-0:
        Processor-0: free
        Processor-4: free
    Core-1:
        Processor-1: free
        Processor-5: free
    Core-2:
        Processor-2: free
        Processor-6: free
    Core-3:
        Processor-3: free
        Processor-7: free

CpuInfo: [nChips=1, nCoresPerChip=4, hyper-threading=true, nProcessors=8, procIds=0,1,2,3,4,5,6,7]

Chip-0:
    Core-0:
        Processor-0: free
        Processor-4: free
    Core-1:
        Processor-1: free
        Processor-5: free
    Core-2:
        Processor-2: assigned to MyPinnedThread (not-started)
        Processor-6: free
    Core-3:
        Processor-3: free
        Processor-7: free

CpuInfo: [nChips=1, nCoresPerChip=4, hyper-threading=true, nProcessors=8, procIds=0,1,2,3,4,5,6,7]

Chip-0:
    Core-0:
        Processor-0: free
        Processor-4: free
    Core-1:
        Processor-1: free
        Processor-5: free
    Core-2:
        Processor-2: bound to MyPinnedThread (running pid=2180)
        Processor-6: free
    Core-3:
        Processor-3: free
        Processor-7: free
...