Maison  >  Article  >  Java  >  [JAVA] L'apparition et la solution d'une impasse

[JAVA] L'apparition et la solution d'une impasse

php是最好的语言
php是最好的语言original
2018-08-06 13:44:333126parcourir

                                         Transfert entre deux comptes Situation

Sous thread unique, ce code est définitivement correct, mais il y a un problème en multi-threading

Verrouillez maintenant il, le code verrouillé est le suivant

void transfer(Account from,Account to,int money){
    from.setAmount(from.getAmount()-money);
    to.setAmount(to.getAmount()+money);
}
synchronisé, c'est-à-dire le verrouillage de l'objet, le premier synchronisé verrouille l'objet from et le second synchronisé verrouille l'objet to.

Dans le cas du multi-threading, un seul thread parmi plusieurs threads peut obtenir le verrouillage d'objet en même temps et faire fonctionner le segment de code dans le verrouillage d'objet

Mais après avoir ajouté le verrouillage d'objet , il y a peut-être une impasse !
void transfer(Account from,Account to,int money){
    synchronized(from){
        synchronized(to){
            from.setAmount(from.getAmount()-money);
            to.setAmount(to.getAmount()+money);
        }
    }
}

le transfert (a,b,100) et le transfert (b,a,100) sont effectués en même temps, c'est-à-dire que pendant que a transfère de l'argent à b, b transfère également de l'argent à a

【1】a Transférer de l'argent vers b, thread , l'opération de transfert peut-elle être effectuée

Opération [2] Le verrouillage de l'objet a est nécessaire de toute urgence avant que l'opération de transfert puisse être effectuée

Les deux threads attendent que les autres threads du groupe libèrent le verrou, et cela se produit Deadlock !

2. Pour sortir de l'impasse

Par quels aspects faut-il commencer ?

【1】Rupture de l'attente d'exclusion mutuelle

De manière générale, pour la sécurité du programme, nous devons verrouiller l'objet, donc cette condition ne peut généralement pas être rompue

【2 】Rompez la prise et attendez, c'est-à-dire que l'attente de possession

peut obtenir toutes les ressources en même temps. Dans l'exemple de code, les deux ressources de et vers ne sont pas obtenues en même temps, mais sont obtenues en une seule fois. manière distribuée.

Méthode 1 : ajoutez un court délai d'attente à. Une fois la tentative d'obtention expirée, relâchez immédiatement le verrou initialement maintenu et réessayez après un certain temps

Obtenez le from. et aux serrures. C'est la méthode recommandée

Méthode 2 : ajoutez un verrou global à ce code pour garantir que from et to sont obtenus en même temps. Une fois l'opération de transfert terminée, le verrou global est libéré. C'est relativement sûr, mais il existe de nombreux comptes bancaires et les opérations de transfert sont très fréquentes. Utiliser cette méthode entraînera inévitablement une baisse importante des performances

[3] Rompre la boucle d'attente

Obtenir des ressources. dans l'ordre, les opérations de transfert sont effectuées en fonction de la taille de l'ID de compte. Les comptes avec des ID plus petits effectuent d'abord les opérations de transfert, et les comptes avec des ID plus grands effectuent des

opérations de transfert plus tard. Mais dans la vraie vie, certaines choses n'ont pas d'identification, c'est-à-dire pas d'ordre. À ce moment-là, il faut leur forcer l'ordre.

【4】Rompez l'attente irrévocable

Ajoutez un délai d'attente en dernier recours L'opération de transfert de l'utilisateur a échoué et l'expérience utilisateur n'est pas bonne

Solution personnellement recommandée :

Sacrifiez le court temps d'attente de l'utilisateur et utilisez la méthode 1 dans [2]

Articles connexes :

Le concept et la solution de blocage en Java

La notion d'impasse et les conditions d'impasse

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn