M-x customize-group
, затем скажите ему, что Вы хотите настроить scheme
. Блуждайте по странице немного, и Вы будете видеть "Название программы Схемы", которое можно изменить, если интерпретатор схемы не называют scheme
.
можно также найти Шарлатана полезным - http://www.neilvandyke.org/quack/
Если я понимаю вашу проблему, одним из способов было бы адаптивно засыпать потоки, подобно тому, как воспроизведение видео выполняется в Java. Если вы знаете, что хотите использовать ядро на 50%, ваш алгоритм должен засыпать примерно 0,5 секунды - потенциально распределяться в течение секунды (например, 0,25 секунды вычисления, 0,25 секунды сна и т. Д.). Вот пример из моего видеоплеера.
long starttime = 0; // variable declared
//...
// for the first time, remember the timestamp
if (frameCount == 0) {
starttime = System.currentTimeMillis();
}
// the next timestamp we want to wake up
starttime += (1000.0 / fps);
// Wait until the desired next time arrives using nanosecond
// accuracy timer (wait(time) isn't accurate enough on most platforms)
LockSupport.parkNanos((long)(Math.max(0,
starttime - System.currentTimeMillis()) * 1000000));
Этот код будет переходить в спящий режим на основе значения кадров в секунду.
Чтобы ограничить использование памяти, вы можете заключить создание объекта в фабричный метод, и использовать какой-то семафор с ограниченными разрешениями в качестве байтов, чтобы ограничить общий предполагаемый размер объекта (вам необходимо оценить размер различных объектов, чтобы нормировать семафор).
package concur;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class MemoryLimited {
private static Semaphore semaphore = new Semaphore(1024 * 1024, true);
// acquire method to get a size length array
public static byte[] createArray(int size) throws InterruptedException {
// ask the semaphore for the amount of memory
semaphore.acquire(size);
// if we get here we got the requested memory reserved
return new byte[size];
}
public static void releaseArray(byte[] array) {
// we don't need the memory of array, release
semaphore.release(array.length);
}
// allocation size, if N > 1M then there will be mutual exclusion
static final int N = 600000;
// the test program
public static void main(String[] args) {
// create 2 threaded executor for the demonstration
ExecutorService exec = Executors.newFixedThreadPool(2);
// what we want to run for allocation testion
Runnable run = new Runnable() {
@Override
public void run() {
Random rnd = new Random();
// do it 10 times to be sure we get the desired effect
for (int i = 0; i < 10; i++) {
try {
// sleep randomly to achieve thread interleaving
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
// ask for N bytes of memory
byte[] array = createArray(N);
// print current memory occupation log
System.out.printf("%s %d: %s (%d)%n",
Thread.currentThread().getName(),
System.currentTimeMillis(), array,
semaphore.availablePermits());
// wait some more for the next thread interleaving
TimeUnit.MILLISECONDS.sleep(rnd.nextInt(100) * 10);
// release memory, no longer needed
releaseArray(array);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
// run first task
exec.submit(run);
// run second task
exec.submit(run);
// let the executor exit when it has finished processing the runnables
exec.shutdown();
}
}
Вы можете получить много информации об использовании ЦП и памяти через JMX , но я не думаю, что он позволяет какие-либо активные манипуляции.
Для управления использованием ЦП до некоторой степени вы можете использовать Thread.setPriority () .
Что касается памяти, не существует такой вещи, как поточная память. Само понятие потоков Java означает разделяемую память. Единственный способ контролировать использование памяти - использовать параметры командной строки, такие как -Xmx, но нет возможности управлять настройками во время выполнения.
Вы можете назначить разные приоритеты потокам, чтобы наиболее релевантный поток планировался чаще.
Посмотрите на этот ответ , чтобы узнать, поможет ли это.
Когда все запущенные потоки имеют одинаковый приоритет, они могут работать следующим образом:
t1, t2, t3, t1, t2, t3, t1, t2, t3
Когда вы назначаете другой приоритет одному из них это может выглядеть так:
t1, t1, t1, t1, t2, t1, t1, t1 t3.
То есть первый поток выполняется «чаще», чем остальные.
Thread.setPriority () может помочь, но не позволяет ограничить использование ЦП потоком. Фактически, я не слышал о какой-либо библиотеке Java, которая бы это делала.
Возможно, можно было бы реализовать такое средство при условии, что ваши потоки готовы к сотрудничеству. Ключ состоит в том, чтобы потоки периодически вызывались в настраиваемый планировщик, а планировщик отслеживал использование ЦП потока с помощью JMX. Но проблема в том, что если какой-то поток не выполняет вызов планировщика достаточно часто, он может превысить пределы регулирования. И вы ничего не можете поделать с потоком, который застревает в цикле.
Еще один теоретический способ реализации - использовать Isolates. К сожалению, вам будет сложно найти JVM общего назначения, реализующую изоляты. Кроме, стандартные API-интерфейсы позволяют контролировать только изолятор, но не потоки в изоляторе.
Единственный способ ограничить использование ЦП потоков - это заблокировать ресурс или часто вызывать yield ().
Это не ограничивает использование ЦП ниже 100%, но дает другие потоки и обрабатывает больше временных интервалов.
Забота о форумах Java . В основном рассчитываете время выполнения, а затем ждете, когда у вас слишком много времени. Как упоминалось в исходном потоке, выполнение этого в отдельном потоке и прерывание рабочего потока даст более точные результаты, как и усреднение значений с течением времени.
import java.lang.management.*;
ThreadMXBean TMB = ManagementFactory.getThreadMXBean();
long time = new Date().getTime() * 1000000;
long cput = 0;
double cpuperc = -1;
while(true){
if( TMB.isThreadCpuTimeSupported() ){
if(new Date().getTime() * 1000000 - time > 1000000000){ //Reset once per second
time = new Date().getTime() * 1000000;
cput = TMB.getCurrentThreadCpuTime();
}
if(!TMB.isThreadCpuTimeEnabled()){
TMB.setThreadCpuTimeEnabled(true);
}
if(new Date().getTime() * 1000000 - time != 0)
cpuperc = (TMB.getCurrentThreadCpuTime() - cput) / (new Date().getTime() * 1000000.0 - time) * 100.0;
}
//If cpu usage is greater then 50%
if(cpuperc > 50.0){
//sleep for a little bit.
continue;
}
//Do cpu intensive stuff
}
Если вы запускаете потоки в отдельном процессе, вы можете ограничить использование памяти и ограничьте количество процессоров или измените приоритет этих потоков.
Однако все, что вы сделаете, скорее всего, приведет к увеличению накладных расходов и сложности, что часто приводит к обратным результатам.
Если вы не объясните, почему вам это нужно (например, у вас есть плохо написанная библиотека, которой вы не доверяете и не можете получить поддержку) Я бы посоветовал вам это не делать.
Причина, по которой нелегко ограничить использование памяти, заключается в том, что используется только одна куча. Таким образом, объект, который используется в одном потоке, может использоваться в другом и не назначается тому или иному потоку.
Ограничение использования ЦП означает остановку всех потоков, чтобы они ничего не делали, однако лучший подход - убедиться, что потоки не тратят впустую ресурсы ЦП и активны только для выполнения работы, которую необходимо выполнить, и в этом случае вы не захотите останавливать их в выполнении.
Почему бы вместо "многопоточности" не использовать совместную многозадачность, Было бы интересно посмотреть, сможете ли вы манипулировать http://www.janino.net/ , чтобы запустить программу в течение определенного времени / набора инструкций, а затем остановить и запустить следующую программу. По крайней мере, так это честно, дайте всем один и тот же отрезок времени ...
Чтобы уменьшить нагрузку на ЦП, вы хотите, чтобы ваши потоки находились внутри общих циклов if и while .
while(whatever) {
//do something
//Note the capitol 'T' here, this sleeps the current thread.
Thread.sleep(someNumberOfMilliSeconds);
}
Сон на несколько сотен миллисекунд приведет к значительно уменьшить использование ЦП с незначительным или незаметным результатом в производительности.
Что касается памяти, я бы запустил профилировщик для отдельных потоков и сделал некоторую настройку производительности. Если вы ограничили объем памяти, доступной для потока, я думаю, что вероятно исключение нехватки памяти или голодание потока. Я бы доверил JVM предоставить столько памяти, сколько требуется потоку, и работать над сокращением использования памяти, сохраняя в области видимости только важные объекты в любой момент времени.