Pergunta

Qual é a diferença entre um Collections.synchronizedMap () e um invólucro em torno de um HashMap com todos os métodos sincronizados. Eu não vejo nenhuma diferença becuase Collections.synchronizedMap () mantém internamente o mesmo bloqueio para todos os métodos.

Basicamente, o que é a diferença entre os seguintes trechos de código

Class C {    
    Object o;

    public void foo() {
       synchronized(o) {
           // thread safe code here
       }
    }
}

e

Class C {
    Object o;

    public synchronized void foo() {

    }
}
Foi útil?

Solução

Há apenas uma diferença:

Collections.synchronizedMap é capaz para utilizar um monitor diferente de si mesmo.

Usando métodos sincronizados é o mesmo que usar sychnchonized(this)-blocos, o que significa, o invólucro seria o monitor e pode ser bloqueado a partir do exterior do invólucro.

Se você não quer uma aplicação externa para bloquear o seu monitor, você precisa escondê-lo.

Por outro lado, se você quiser chamar vários métodos em uma forma thread-safe, é a maneira mais fácil para bloquear toda a coleção (mas não é muito escalável, de fato).

Ps:. Para a reutilização, é melhor delegar as chamadas de método para um backup-Map do que para substituir a classe, porque você pode mudar para outra aplicação Map depois, sem mudar seu wrapper

Outras dicas

Ambas as abordagens adquirir um monitor no objeto e assim deve executar exatamente o mesmo. A principal razão para a diferença é arquitetônica. O invólucro sincronizado permite que se estende da rosca não-seguro variação básica facilmente.

Tendo dito que não usar, uso ConcurrentHashMap. Ele usa segmentação de bloqueio de modo que é muito mais rápido do que a utilização quer de aproximação (como eles são os mesmos em termos de contenção + sobrecarga). Bloqueio particionamento permite que os segmentos da matriz de suporte para ser bloqueado de forma independente. Isto significa que é menos provável que dois tópicos pedirá para adquirir o mesmo bloqueio.

Não reinventar a roda e usar o que é fornecido pela API.

Você deve sempre decorar em vez de amontoar tudo e todos Feartures em uma classe de destaque grande.

Sempre tomar a planície Mapa e decorá-lo com coleções ou usar um java.util.concurrent e usar um bloqueio real, então pode-se atomicamente inspecionar e atualizar o mapa. Amanhã você pode querer mudar a tabela de hash a uma Treemap e você estará em apuros se o seu preso com um hashtable.

Então, por que você pergunta? :) Você realmente acredita que se a classe é colocado no pacote java.util, em seguida, alguma magia acontece e seus trabalhos de código java, de alguma forma complicada?

É realmente apenas envolve todos os métodos com sincronizados {} bloco e nada mais.

UPD:. A diferença é que você tem muito menos chances de cometer um erro se você usar a coleção sincronizado em vez de fazer todas as coisas sincronização por si mesmo

UPD 2: como você pode ver nas fontes que eles usam 'mutex'-objeto como monitor. Quando você usa sincronizados modificador na assinatura do método (ou seja synchronized void doSmth()) instância atual do seu objeto (ou seja this) é usado como um monitor. Dois blocos de código abaixo são os mesmos:

1.

synchronized public void doSmth () {
   someLogic ();
   moreLogic ();
}

synchronized public static void doSmthStatic () {
   someStaticLogic ();
   moreStaticLogic ();
}

2.

public void doSmth () {
   synchronized (this) {
      someLogic ();
      moreLogic ();
   }
}

public static void doSmthStatic () {
   synchronized (ClassName.class) {
      someStaticLogic ();
      moreStaticLogic ();
   }
}

Se a segurança do thread é o caso, o uso de simultaneidade estruturas de dados pacote. Usando a classe wrapper irá reduzir todos os acessos ao mapa em uma fila sequencial.

a) Threads esperando para fazer operações em totalmente diferentes pontos do mapa estará esperando para o mesmo bloqueio. Com base no número de threads isso pode afetar o desempenho do aplicativo.

b) Considerar operações compostas no mapa. Usando um invólucro com um bloqueio único não vai ajudar. Por exemplo. "Olhe, se presentes, em seguida, adicione" tipo de operações. Tópico syncronization vai voltar a ser um problema.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top