J'ai un réseau de threads Java (programmation basée sur le flux) communiquant via des canaux à capacité fixe - fonctionnant sous Windows XP. Ce que nous attendions, basé sur notre expérience avec les threads «verts» (non préemptifs), serait que les threads changeraient de contexte moins souvent (réduisant ainsi le temps CPU) si les canaux étaient plus grands. Cependant, nous avons constaté que l'augmentation de la taille des canaux ne change rien à l'exécution. Ce qui semble se passer est que Java décide de changer de threads même si les canaux ne sont pas pleins ou vides (c'est-à-dire même si un thread n'a pas à suspendre), ce qui coûte du temps CPU sans avantage apparent. La modification des priorités Thread ne fait pas de différence notable. Ma question est de savoir s'il y a moyen de persuader Java de ne pas faire de changements de contexte inutiles, mais de bloquer la commutation jusqu'à ce qu'il soit vraiment nécessaire de changer de threads. Y a-t-il un moyen de changer la logique d'envoi de Java? Ou réagit-il à quelque chose auquel je n'ai pas prêté attention ?! Ou existe-t-il d'autres mécanismes d'asynchronisme, par ex. Fabriques de threads, Runnable (s), peut-être même démons (!). La réponse semble être non évidente, car jusqu'à présent, aucun de mes correspondants n'a trouvé de réponse (y compris les deux derniers professeurs de CS). Ou peut-être que je manque quelque chose qui est si évident que les gens ne peuvent pas imaginer que je ne le sache pas ...Commutateurs de contexte Java inutiles
J'ai ajouté le code d'envoi et de réception ici - pas très élégant, mais il semble fonctionner ... ;-) Au cas où vous vous poseriez la question, je pensais que la logique goLock dans 'send' pouvait causer le problème, mais le supprimer temporairement ne faisait aucune différence. J'ai ajouté le code pour envoyer et recevoir ...
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;
}
merci de demander! J'ai discuté la même question sur le forum Sun, et voici mon dernier message sur ce forum:
Notre meilleure estimation est en ce moment que cet effet résulte de logique de programmation Windows.
Microsoft semble reconnaître que ce domaine a besoin d'une certaine amélioration car il introduit UMS - je cite: « UMS est recommandé pour les applications avec des exigences de haute performance qui ont besoin pour fonctionner efficacement de nombreux threads simultanément sur les systèmes multiprocesseurs ou multicœurs . ... UMS est disponible en commençant par les versions 64 bits de Windows 7 et Windows Server 2008 R2 Cette fonctionnalité n'est pas disponible sur les versions 32 bits de Windows. " Espérons que Java profitera de UMS dans les versions ultérieures de .
Merci pour votre aide!
Quel JDK utilisez-vous? Essayez de faire la même chose sous Linux ... si ça marche mieux, c'est XP. – ReneS
Des nouvelles à ce sujet? Avez-vous trouvé une solution? – ReneS
Cela ne sert à rien que Java utilise les threads OS pour JSE et JEE. Cela signifie que vous êtes à la merci du fonctionnement de votre système d'exploitation. Pour un meilleur contrôle de la commutation de contexte, vous pouvez utiliser un système d'exploitation en temps réel. Cependant, votre problème est peut-être que votre système d'exploitation essaie d'être équitable vis-à-vis des threads de votre processus et que vous avez plus de threads que vous avez de cœurs, il doit donc les échanger. Je dirais que vous avez moins de fil que les noyaux et il devrait changer beaucoup moins. –