217 votes

Ce qui est la raison pour laquelle « synchronisé » n’est pas autorisé dans les méthodes d’interface Java 8 ?

Dans Java 8, je peux facilement écrire:

interface Interface1 {
    default void method1() {
        synchronized (this) {
            // Something
        }
    }

    static void method2() {
        synchronized (Interface.class) {
            // Something
        }
    }
}

Je vais avoir la synchronisation complète de la sémantique que je peux utiliser également dans les classes. Je ne peux pas, cependant, l'utilisation de l' synchronized modificateur sur les déclarations de méthode:

interface Interface2 {
    default synchronized void method1() {
        //  ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
    }

    static synchronized void method2() {
        // ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
    }
}

Maintenant, on peut dire que les deux interfaces se comportent de la même façon, sauf qu' Interface2 établit un contrat sur method1() et method2(), ce qui est un peu plus forte que ce qu' Interface1 . Bien sûr, on peut dire aussi qu' default des implémentations ne devrait pas faire d'hypothèses sur la mise en œuvre concrète de l'état, ou le mot-clé tout simplement de ne pas tirer son poids.

Question:

Quelle est la raison de la JSR 335 par exemple décidé de ne pas appuyer synchronized sur les méthodes d'interface?


Note, avant que cette question est très fermé: Pour ajustement de Débordement de Pile Q&r format: je suis à la recherche d'autorité citations seulement, pas de la spéculation. Une réponse ferme à cette question sera probablement aider beaucoup de futurs visiteurs de cette question, donc merci de ne pas le fermer avec impatience.

270voto

Brian Goetz Points 6062

C'était une décision délibérée, plutôt que d'une omission (comme cela a été suggéré ailleurs.) Tout d'abord il peut sembler évident que l'on aurait envie de soutenir l' synchronized modificateur sur les méthodes par défaut, il s'avère que cela serait dangereux, et qu'il était donc interdite.

Synchronisé méthodes sont un raccourci pour une méthode qui se comporte comme si tout le corps est enfermé dans un synchronized bloc dont le verrou de l'objet est le récepteur. Il peut sembler judicieux d'étendre cette sémantique à des méthodes par défaut; après tout, ils sont les méthodes d'instance avec un récepteur de trop. (À noter qu' synchronized méthodes sont entièrement syntaxique, l'optimisation; ils ne sont pas nécessaires, ils sont plus compacts que la correspondante synchronized bloc. Il y a un argument raisonnable que c'était un prématuré syntaxique d'optimisation, en premier lieu, et qui se synchronise les méthodes de causer plus de problèmes qu'elles n'en résolvent, mais que le navire a navigué il y a longtemps.)

Alors, pourquoi sont-ils dangereux? La synchronisation est sur le verrouillage. Le verrouillage est sur la coordination de l'accès partagé à mutable état. Chaque objet doit avoir une synchronisation de la politique qui détermine les verrous de la garde qui les variables d'état. (Voir la Java de la Simultanéité dans la Pratique, la section 2.4.)

De nombreux objets de l'utiliser comme leur synchronisation de la politique de la Java motifs du Moniteur (JCiP 4.1), dans lequel l'état d'un objet est gardée par son intrinsèque de verrouillage. Il n'y a rien de magique ou de spécial à propos de ce modèle, mais il est pratique, et l'utilisation de l' synchronized mot-clé sur les méthodes suppose implicitement ce modèle.

C'est l'objet qui possède l'état qui arrive à déterminer que l'objet de la stratégie de synchronisation. Mais les interfaces ne sont pas propres l'état des objets dans lesquels ils sont mélangés dans. Donc, en utilisant une méthode synchronisée dans une interface suppose un particulier de synchronisation de la politique, mais vous n'avez pas de base raisonnable de supposer, de sorte qu'il pourrait bien être le cas que l'utilisation de la synchronisation fournit aucun autre thread de sécurité que ce soit (vous pourriez être en synchronisation sur le mauvais verrouillage). Ce serait vous donner le faux sentiment de confiance que vous avez fait quelque chose à propos de la sécurité des threads, et aucun message d'erreur vous indique que vous êtes en supposant que la mauvaise synchronisation de la politique.

Il est déjà assez dur de toujours maintenir une synchronisation de la politique pour un fichier source unique; il est encore plus difficile de s'assurer qu'une sous-classe correctement adhérer à la synchronisation de la politique définie par sa super-classe. Essayer de le faire entre ces faiblement couplé classes (une interface et éventuellement le nombre de classes qui l'implémentent) serait presque impossible et très sujette aux erreurs.

Compte tenu de tous ces arguments contre, ce serait l'argument? Il semble qu'ils sont pour la plupart au sujet de faire des interfaces se comportent plus comme des traits. Alors que c'est un désir compréhensible, le centre de conception des méthodes par défaut est l'évolution de l'interface, pas de "Traits--". Où les deux pourrait être obtenu de manière constante, nous nous sommes efforcés de le faire, mais où l'on est en conflit avec les autres, nous avons eu à choisir en faveur de l'objectif de conception principale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X