У меня есть сеть потоков Java (потоковое программирование), осуществляющая связь через каналы с фиксированной пропускной способностью - работает под управлением WindowsXP. То, что мы ожидали, основываясь на нашем опыте с «зелеными» потоками (без превентивного), будет заключаться в том, что потоки будут переключать контекст реже (тем самым уменьшая время процессора), если каналы будут сделаны больше. Однако мы обнаружили, что увеличение размера канала не влияет на время выполнения. Кажется, что происходит то, что Java решает переключать потоки, даже если каналы не заполнены или пустые (т. Е. Хотя поток не должен приостанавливаться), что требует процессорного времени без видимых преимуществ. Также изменение приоритетов нитей не создает заметных различий.Необязательные переключатели контекста Java
Мой вопрос заключается в том, есть ли способ убедить Java не создавать ненужные переключатели контекста, но отключаться до тех пор, пока нет необходимости переключать потоки - есть ли способ изменить логику диспетчеризации Java? Или это реагирует на то, на что я не обращал внимания ?! Или существуют другие механизмы асинхронизма, например. Заводы, Runnable (s), возможно, даже демоны (!). Ответ кажется неочевидным, так как до сих пор ни один из моих корреспондентов не получил ответа (включая последние два профессора CS). Или, может быть, мне не хватает чего-то настолько очевидного, что люди не могут себе представить, что я этого не знаю ...
Я добавил код отправки и получения здесь - не очень элегантный, но, похоже, он работает ... ;-) В случае, если вам интересно, я думал, что логика goLock в «send» может вызвать проблему, но ее удаление временно не имеет никакого значения. Я добавил код для отправки и приема ...
public synchronized Packet receive() {
if (isDrained()) {
return null;
}
while (isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
close();
return null;
}
if (isDrained()) {
return null;
}
}
if (isDrained()) {
return null;
}
if (isFull()) {
notifyAll(); // notify other components waiting to send
}
Packet packet = array[receivePtr];
array[receivePtr] = null;
receivePtr = (receivePtr + 1) % array.length;
//notifyAll(); // only needed if it was full
usedSlots--;
packet.setOwner(receiver);
if (null == packet.getContent()) {
traceFuncs("Received null packet");
} else {
traceFuncs("Received: " + packet.toString());
}
return packet;
}
synchronized boolean send(final Packet packet, final OutputPort op) {
sender = op.sender;
if (isClosed()) {
return false;
}
while (isFull()) {
try {
wait();
} catch (InterruptedException e) {
indicateOneSenderClosed();
return false;
}
sender = op.sender;
}
if (isClosed()) {
return false;
}
try {
receiver.goLock.lockInterruptibly();
} catch (InterruptedException ex) {
return false;
}
try {
packet.clearOwner();
array[sendPtr] = packet;
sendPtr = (sendPtr + 1) % array.length;
usedSlots++; // move this to here
if (receiver.getStatus() == StatusValues.DORMANT || receiver.getStatus() == StatusValues.NOT_STARTED) {
receiver.activate(); // start or wake up if necessary
} else {
notifyAll(); // notify receiver
// other components waiting to send to this connection may also get
// notified,
// but this is handled by while statement
}
sender = null;
Component.network.active = true;
} finally {
receiver.goLock.unlock();
}
return true;
}
спасибо за вопрос! Я обсуждал тот же вопрос на форуме Sun, а вот мой последний пост на этом форуме:
Наша догадка сейчас является то, что этот эффект является результатом планирования логики Windows' .
Microsoft, кажется, признают, что эта область нуждается в некотором улучшении как это введение UMS - я цитирую: «UMS рекомендуется для применения с высокими требованиями к производительности, которые должны эффективно работать многие потоки одновременно на многопроцессорных или многоядерных системах . ... UMS - , доступный начиная с 64-разрядных версий Windows 7 и Windows Server 2008 R2. Эта функция недоступна в 32-разрядных версиях Windows. " Надеюсь, Java воспользуется UMS в более позднем выпуске .
Благодарим за помощь!
Какой JDK вы используете? Попробуйте запустить то же самое под Linux-сервером ... если он работает лучше, это XP. – ReneS
Любые новости по этому поводу? Вы нашли решение? – ReneS
Не стоит ничего, что Java использует потоки ОС для JSE и JEE. Это означает, что вы находитесь на милость своей операционной системы. Для лучшего управления переключением контекста вы можете использовать операционную систему реального времени. Однако проблема может заключаться в том, что ваша ОС пытается быть честной с потоками в вашем процессе, и у вас больше потоков, чем у вас есть ядра, поэтому вам приходится их менять. Я бы предположил, что у вас меньше потоков, чем ядер, и он должен переключиться намного меньше. –