Приоритеты потоков не влияют

Я пишу симулятор голодания на Java. Однако, когда я запускаю его, он просто не работает почти всегда. Я работаю на MacOS. Код похож на:

public class StarvationNew {
private static SharedObject sharedObject = new SharedObject(); // to jest ten obiekt (operacja) na ktorym sie blokuje
private static volatile boolean isActive = true;

public static void main(String[] args) {
    Thread t1 = new Thread(new Worker(), "Thread_1");
    Thread t2 = new Thread(new Worker(), "Thread_2");
    Thread t3 = new Thread(new Worker(), "Thread_3");

    t1.setPriority(Thread.MAX_PRIORITY);
    t2.setPriority(Thread.MAX_PRIORITY);
    t3.setPriority(Thread.MIN_PRIORITY);

    t1.start();
    t2.start();
    t3.start();


    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    isActive = false;

}

private static class Worker implements Runnable {
    private int runCount = 0;

    @Override
    public void run() {
        while(isActive) {
            sharedObject.playOperation();
            runCount++;
        }
        System.out.println("--------");
        System.out.println(Thread.currentThread().getName() + " ended with: " + runCount);
        System.out.println("--------");
    }
}

}

а SharedObject просто имитирует длительные операции и выглядит следующим образом:

public class SharedObject {
    public synchronized void playOperation() {
        try {
            // long operations
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(150);
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Интересно, в чем ошибка в этом коде?

1 ответ

Решение

При работе с потоками Java нужно помнить о нескольких вещах.

  1. Правила для приоритетов потоков сильно зависят от системы. Когда виртуальная машина полагается на реализацию потока на платформе хоста, планирование потока зависит от реализации этого потока.
  2. Практическое правило. В любой момент времени выполняется поток с наивысшим приоритетом. Однако это не гарантируется. Планировщик потока может выбрать запуск потока с более низким приоритетом, чтобы избежать голодания. По этой причине используйте приоритет потока только для того, чтобы повлиять на политику планирования в целях повышения эффективности. Не полагайтесь на правильность алгоритма.
  3. Что произойдет, если существует более одного работающего потока с одинаковым (наивысшим) приоритетом? Выбирается один из потоков с наивысшим приоритетом. Это полностью зависит от планировщика потоков, как проводить арбитраж между потоками с одинаковым приоритетом. Язык программирования Java не дает гарантии того, что все потоки обрабатываются справедливо.

Как было сказано выше, я не вижу ничего необычного в следующем выводе на моем компьютере с Windows 10 (Java 8):

Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_1
Thread_3
--------
Thread_1 ended with: 34
--------
--------
Thread_2
Thread_3 ended with: 1
--------
--------
Thread_2 ended with: 1
--------

Посмотрите на это для получения дополнительной информации.

Другие вопросы по тегам