-1

Je code suivant:StringBuffer ou méthode synchronisée?

public class MyLogger { 
    private StringBuilder logger = new StringBuilder(); 

    public void log(String message, String user) { 
     logger.append(message); 
     logger.append(user); 
    } 
} 

Le programmeur doit garantir qu'un seul objet myLogger fonctionne correctement pour un système multi-thread. Comment ce code doit-il être modifié pour être compatible avec les threads?

A. synchronisent la méthode du journal

B. remplacer StringBuilder avec StringBuffer

S'il vous plaît conseiller la meilleure approche.

+0

Donc, ce accumule dans l'enregistreur, quel est le point ? –

+0

Je n'utiliserais probablement pas non plus, préférant une instance de classe 'LogEntry' qui contient une copie des deux chaînes et une commande à un thread de journalisation qui attend à la fin d'une file d'attente de blocage. –

Répondre

3

StringBuffer ne suffit pas pour garantir que les deux informations sont toujours envoyées groupées:

logger.append(message); 
    logger.append(user); 

Il garantit seulement que append() ne sera pas invoqué de manière simultanée et donc vous ne risquez pas de briser la état de l'objet StringBuffer.
Vous pourriez en effet avoir deux fils qui s'entrelacent lors de l'appel log() et obtenir ces invocations:

Discussion 1: logger.append (message);

Fil 2: logger.append (message);

Fil 1: logger.append (utilisateur);

Fil 2: logger.append (utilisateur);

Il en est ainsi mieux:

public synchronized void log(String message, String user) { 
     logger.append(message); 
     logger.append(user); 
    } 

Vous pouvez également faire la synchronisation sur l'objet logger privé.
Ce qui a l'avantage de ne pas permettre au client de la classe de le verrouiller en dehors de la classe.

+2

Vous pouvez mentionner que la synchronisation sur un objet privé est préférable à l'utilisation de 'synchronized' sur la signature de la méthode. –

+1

@Alvin Thompson bon conseil. Je l'ai ajouté. – davidxxx

+0

Merci @davidxxx pour la bonne description. S'il vous plaît laissez-moi savoir si ma compréhension est fausse: dire, Thread 1 a eu la chance d'exécuter logger.append (message); donc T1 a le verrou sur l'objet SB et à la fin de l'exécution de la méthode, il va libérer le verrou sur SB? donc T2 peut exécuter logger.append (message); et donc un problème peut survenir? Est-ce que c'est ce que tu voulais décrire? –

0

Utilisez A, parce que si vous choisissez d'utiliser StringBuffer vous pouvez gâcher le journal: Cela pourrait se produire avec StringBuffer (allez générer un journal incorrect):

logger.append(message); < Thread A 
logger.append(message); < Thread B 
logger.append(user); < Thread A 
logger.append(user); < Thread B