2012-10-05 2 views
2

J'utilise singleton pour enregistrer tous les événements se produisant simoultanously dans le système.Singleton avec Lock - blocage possible? en java

public class Singleton { 
    private static Lock dbLock; 
    protected Singleton() {} 
    private static class SingletonHolder { 
     private final static Singleton instance = new Singleton(); 
    } 
    public static Singleton getInstance() { 
     return SingletonHolder.instance; 
    } 
    public void recordEvent(Event ev) { 
     dbLock.lock(); 
    try { 
      database.insert(ev); 
     } finally { 
     dbLock.unlock(); 
    } 
    } 
    public File lockAndGetDB() { 
     dbLock.lock(); 
     return database.getFile(); 
    } 
    public void unlockDB() { 
     dbLock.unlock(); 
    } 
} 

Toutes les heures je veux verrouiller l'événement d'enregistrement pour envoyer la base de données sur Internet.

file = Singleton.getInstance().lockAndGetDB(); 
try { 
    sendViaHTTP(file); 
} 
finally { 
    Singleton.getInstance().unlock(); 
} 

Y a-t-il des blocages possibles? Est-ce que le fil est sûr?

EDITED. (essayez/enfin ajouté pour l'envoi viaHTTP) Mais ce n'est pas le problème principal. La question est, s'il y a des threads qui attendent sur dbLock.lock(); à recordEvent (Event ev) sont mon Singleton.getInstance(). unlock(); sera en mesure d'entrer le code getInstance() et de déverrouiller?

+1

L'implémentation d'un tel verrou va avoir un impact énorme sur les performances de cette application ... y a-t-il une raison pour laquelle vous ne voulez pas utiliser JDBC? –

+0

@JordanDenison Je l'implémente dans Android. Mais il est question générale de java –

Répondre

1

Plus probablement que non, oui, il peut y avoir des blocages. Que se passe-t-il si une erreur se produit pendant database.getFile ou sendViaHTTP? Il n'y a pas de motif try/finally pour s'assurer que Lock.unlock est appelée.

+0

C'est une erreur d'exemple, j'ai essayé de le rendre plus simple. Oui bien sur il y a try/finally quand j'envoie viaHTTP. Mais ce n'est pas le point. –

+1

Il est impossible d'acquérir Lock et de ne pas faire aussi Database.getFile. Pour votre implémentation actuelle, cette opération ne peut jamais échouer. Pourtant, il se produit entre le 'lock' et le' try' donc j'imagine qu'un analyseur de code comme 'FindBugs' se plaindra à juste titre. –

0

Les blocages surviennent lorsque vous acquérez des verrous dans différents ordres. Comme il n'y a qu'un seul verrou ici, la question ne se pose pas. Votre cas ressemble plus à un candidat pour un verrou en lecture-écriture: utilisez des verrous en lecture pour autoriser une simultanéité maximale des opérations SGBD et un verrou en écriture lorsque vous voulez qu'ils arrêtent et envoient le fichier.

+0

@downvoter S'il vous plaît expliquer. Downvotes inexpliquées sont vraiment juste du vandalisme sur le site. Ils aident personne. – EJP

+0

Des blocages peuvent également survenir lorsqu'un verrou est acquis mais jamais libéré. Ce que vous décrivez n'est qu'une forme d'impasse. –

+0

@TimBender Non. Ce n'est pas une impasse. C'est juste un verrou. Un blocage est une chaîne circulaire de processus, chacun contenant une ressource que le prochain veut. – EJP