2016-08-23 5 views
5

Можем ли мы иметь слабую ссылку на работающий поток, который должен быть остановлен при низкой производительности процессора?java - можем ли мы иметь слабую нить?

Я имею в виду, что-то вроде этой работы?

WeakReference<Thread> ref = new WeakReference<Thread>(new Thread(){ 
    public void run(){ 
     while(true){ /* your code */ } 
    } 
}); 

Таким образом, я хочу нить, чтобы иметь низкий приоритет для выполнения, я имею в виду, когда производительность процессора LOW и CPU занимается полностью, выполнение этого потока автоматически прекращается.

Есть некоторые потоки, которые НЕ имеют высокий приоритет и должны быть прерваны и прекращены при низкой производительности ЦП.

+1

Нет связи между слабыми ссылками и приоритетом нити ... – assylias

+0

@assylias - так что мне делать? – user3840019

+1

http://stackoverflow.com/questions/20333150/java-multithreading-thread-priority – assylias

ответ

1

Для достижения вашей цели необходимо использовать thread priority.

Идея weak reference заключается в том, чтобы разрешить сбор мусора раньше. Но в случае потоков нет смысла использовать его, поскольку сам поток является gc root и не будет мусором, собранным в состоянии RUNNING.

+0

ли JVM завершает потоки в LOW_PERIORITY когда начались новые потоки с HIGH_PRIORITY? – user3840019

+0

@ user3840019 любое такое поведение было бы зависимым от ОС. Скорее всего, поток с низким приоритетом получит меньше процессорного времени, чем поток с более высоким приоритетом, но он не будет прекращен. – John

+0

@ пользователь3840019 нет. приоритет потока - это то, сколько процессорного времени будет выделено каждому потоку с помощью os scheduler – vsminkov

2

Короткий ответ: No. Сожалею!

В стандартном API нет такого механизма, и вы не можете использовать WeakReference для создания такой вещи, потому что ссылки относятся только к достижимости объектов, а не к активности процессора.

Но это не означает, что аналогия не является опрятной, и это не значит, что это плохая идея! Мне это нравится.

Надеюсь, вам нужно назначить низкий приоритет потока - но, как уже отмечалось в других местах, это тонкий и быстрый гнев. Низкоприоритетный поток должен уступать место более высоким приоритетам и был бы подходящим для потока while-loop. Опасности заключаются в том, что разные системы планирования OS могут привести к тому, что ваш низкоприоритетный поток будет голодать, особенно если вы не слишком осторожны, чтобы время от времени выделялось потоки с более высоким приоритетом. Вы можете найти поведение с дикой переменной на многопроцессорных процессорах или на отдельных процессорах.

Учитывая, что задача действительно прекращается при загрузке процессора ... вы можете использовать System.nanoTime() для выполнения каждого прохода цикла, а если он превышает некоторый порог, то завершите цикл while. Мне это не очень нравится: он восприимчив к паузам GC и естественным вариациям, которые приводят к прекращению действия.

В качестве альтернативы вы можете использовать JMX для измерения фактической загрузки процессора, см. How to get percentage of CPU usage of OS from java - и прервать цикл while, если он превышает пороговое значение. У вас может быть поток мониторинга, который вызывает Thread.interrupt() для вашего рабочего, чтобы прервать любые блокирующие действия. Я могу себе представить, что вы потратили бы всю жизнь на его настройку - слишком нетерпеливы в некоторых обстоятельствах, слишком летаргичны в других; дико варьирующихся на разных размерах хостов.

И если вы хотите убить потоки, пока они на самом деле запущены ... это начинает очень тяжело. Я начинаю думать, что могут быть другие подходы, но это трудно сказать, не зная больше о более широкой проблеме, которую вы пытаетесь решить.

По-прежнему аккуратный, хотя.

+0

, что в порядке, больше нет возможности реализовать? – user3840019

+0

Я добавлю некоторые мысли к ответу. Однако вы будете катать свой собственный механизм, и это может быть немного чревато сюрпризами. – SusanW

+0

Хорошо проверит. заранее спасибо – user3840019

3

Это не достижимо через слабые ссылки в том виде, как вы описываете. Эта статья хорошо описывает слабые ссылки, поэтому вам может быть интересно: weak reference

Есть две проблемы, которые необходимо решить для этого, легкая и не простая. Я не думаю, что для этого есть что-то в стандартном Java API.

Easy один - оканчиваются «низкий» приоритетные темы:

Простой способ для достижения желаемого поведения будет регистрировать Runnable экземпляры низкого приоритета, в соответствии с вашими правилами применения, в какой-то государственный менеджер. Эти экземпляры будут реализовывать какой-то вид stop() и необязательно поведение pause() и resume() и выставить его в диспетчер состояний, который мог бы остановить все экземпляры на каком-то сигнале. Вы можете просто проверить некоторые volatile boolean в цикле run() для этого.

Не так просто один - определить CPU использование

Либо использовать JNI или какой-то сторонней библиотеки, такие как один из них: How to monitor the computer's cpu, memory, and disk usage in Java?

Вы можете периодически проверять потребление ресурсов с помощью шага 2 , и если вы решите, что есть что-то подозрительное, чтобы уведомить государственного менеджера о завершении невысоких задач.

Смежные вопросы