2015-11-30 4 views
0

J'ai un composant où les threads interrogent certaines ressources et System.currentTimeMillis(); s'il n'y a pas de ressources, ils vont Object.wait(1), parce que je sais que je vais attendre au moins 1 ms (les ressources sont réapprovisionnées quand un thread voit un nouvel horodatage). Cependant, en JVM le Object.wait() provoque ObjectMonitor::TrySpin_VaryDuration, donc le thread brûle CPU quand je lui ai dit d'aller au lit. Y a-t-il un moyen de contourner le problème (meilleure primitive de synchronisation avec des sémantiques similaires?) Mais de revoir le composant pour que les threads passent un sommeil illimité et qu'un seul thread attende? Ou puis-je le désactiver de manière sélective sur cet objet?Object.wait() sans rotation dans JVM

EDIT: Ma question est plutôt stupide. Je devrais vraiment utiliser Thread.sleep(1) comme dit la réponse acceptée (à moins que cela utilise spinlock, aussi - n'a pas confirmé), parce qu'il ne sert à rien de réveiller les threads en attente quand il est temps car ils devraient déjà se réveiller par timeout.

+2

le problème est avec des arguments faibles à 'wait': la mise en œuvre peut décider de spin attendre au lieu de céder. Pourquoi n'utilisez-vous pas une [BlockingQueue] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html) pour la tâche? – BeyelerStudios

Répondre

3

Object.wait(1) est le mauvais outil pour le travail. Utilisez Thread.sleep(1) à la place.

+0

Cela n'encourt-il pas encore une attente limitée? –

+0

La raison de 'Object.wait (1)' est que lorsqu'un thread trouve les ressources, il notifie aux autres threads de les réactiver. D'un autre côté, vous avez raison, ceux-ci devraient se réveiller de toute façon, car il est temps pour eux. –

0

Vous pouvez essayer d'utiliser un indicateur appelé -XX:-UseSpinning

+0

Merci, même si c'est un peu grossier. Et pas vraiment applicable aux JVM modernes: -XX: -UseSpinning \t Activer la rotation naïve sur le moniteur Java avant d'entrer le code de synchronisation du thread du système d'exploitation. (Correspondant à 1.4.2 et 5.0 uniquement.) [1.4.2, plates-formes Windows multiprocesseurs: true] –