Приоритеты потоков не влияют
Я пишу симулятор голодания на 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 нужно помнить о нескольких вещах.
- Правила для приоритетов потоков сильно зависят от системы. Когда виртуальная машина полагается на реализацию потока на платформе хоста, планирование потока зависит от реализации этого потока.
- Практическое правило. В любой момент времени выполняется поток с наивысшим приоритетом. Однако это не гарантируется. Планировщик потока может выбрать запуск потока с более низким приоритетом, чтобы избежать голодания. По этой причине используйте приоритет потока только для того, чтобы повлиять на политику планирования в целях повышения эффективности. Не полагайтесь на правильность алгоритма.
- Что произойдет, если существует более одного работающего потока с одинаковым (наивысшим) приоритетом? Выбирается один из потоков с наивысшим приоритетом. Это полностью зависит от планировщика потоков, как проводить арбитраж между потоками с одинаковым приоритетом. Язык программирования 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
--------
Посмотрите на это для получения дополнительной информации.