J'ai une méthode qui va appeler la méthode à distance via RMI comme suit:

/**
 * Implementation is supposed to be thread safe
 */
public interface Act extends java.rmi.Remote{
    String doSome() throws RemoteException;
}

public class SomeClass {
    private static final Act stub = (Act) Naming.lookup("/server/stub")

    public static void someMethodAccessedByMultipleThreads(){
        System.out.println(stub.doSome());
    }
}

Si la méthode distante est thread-safe, est-il sûr d'appeler someMethodAccessedByMultipleThreads par plusieurs threads?

Ou y a-t-il des problèmes de threading RMI / réseau / quelque chose_else?

1
St.Antario 21 avril 2017 à 11:27

3 réponses

Meilleure réponse

Difficile de discerner exactement de quoi vous parlez, mais je vais faire deux déclarations.

  1. Les stubs distants sont thread-safe. J'ai posé cette question il y a de nombreuses années sur la liste de diffusion [défunte] RMI, et la réponse est venue gravée dans des tablettes de pierre par Bob Scheifler, Ann Wolrath, Peter Jones ou l'un des autres auteurs, pas seulement pour RMI mais pour l'ensemble JDK: il est thread-safe sauf indication contraire du Javadoc.

  2. Les implémentations de méthodes distantes ne sont pas thread-safe. La source de cette assertion est l'énoncé gnomique dans la spécification d'invocation de méthode distante selon lequel RMI ne donne aucune garantie sur toute association entre les threads côté client et les threads côté serveur. La signification occulte de ceci est que vous ne pouvez pas supposer que RMI est monothread sur le serveur.

La conclusion à tirer est que si l'implémentation de votre méthode distante est thread-safe, il en va de même pour l'appeler à partir de plusieurs threads dans n'importe quel client, ou de plusieurs clients simultanément, ce qui revient au même du point de RMI vue.

3
Marquis of Lorne 21 avril 2017 à 09:32

Même quand RMI a essayé, il ne pouvait pas casser les choses ici.

Vous voyez, le point de terminaison , la méthode qui est appelée existe dans une seule JVM. C'est une méthode unique. Si vous avez implémenté cette méthode de manière thread-safe, alors vous êtes bon; sinon vous ne l'êtes pas.

Et à partir de là: quand cette JVM invoque cette méthode; est-ce important qui / ce qui déclenche l'invocation?

En d'autres termes: la sécurité des threads est une propriété locale . Peu importe ce qui se passe sur la machine "cliente"; et comment le protocole est implémenté qui transporte la demande "d'invocation" vers la machine "serveur distant"; à la fin; vous avez affaire à une seule JVM, avec un seul «point de terminaison de méthode».

Si cette chose est mise en œuvre correctement, les choses fonctionneront; sinon ils se briseront; peu importe si les n threads appelant cette méthode recevaient leurs ordres de "l'intérieur du serveur distant" ou d'un autre thread sur un autre système.

Pour que cela soit très clair: il est de votre responsabilité de vous assurer que votre implémentation de cette méthode à utiliser pour RMI est thread-safe. Si vous vous trompez, alors bien sûr, les choses iront mal. Mais il en va de même lorsque plusieurs threads appellent une méthode non RMI qui n'est pas thread-safe.

2
Marquis of Lorne 17 mai 2017 à 22:19

Si je comprends bien la question, vous demandez si les implémentations RMI stub générées par le client sont thread-safe.

Je suis sûr qu'ils sont implémentés thread-safe, mais cela ne semble documenté nulle part. Je ne trouve aucune mention explicite de stubs étant ou non thread-safe dans la spécification RMI. Cela généralement est documenté si quelque chose n'est pas thread-safe.

Dans cette question du forum sur Thread sécurité des stubs RMI quelqu'un mentionne que les stubs RMI sont sans état et donc thread-safe. La personne qui a demandé cela a également effectué un test dans Java 6 qui a confirmé la sécurité des threads des stubs, mais il rappelle également que, comme ce n'est pas dans les spécifications, cela peut changer dans les versions futures (bien que cela soit peu probable à mon avis).

1
kapex 21 avril 2017 à 09:09