Qual é a diferença entre um bloqueio exclusivo e um bloqueio compartilhado?


118

De acordo com a wikipedia,

Os bloqueios compartilhados às vezes são chamados de "bloqueios de leitura" e os bloqueios exclusivos às vezes são chamados de "bloqueios de gravação".

Você pode explicar o raciocínio por trás dos termos "compartilhado" e "exclusivo"?


O bloqueio não exclusivo é outro nome de bloqueio compartilhado?
Ramesh Papaganti de

Respostas:


417

Anotei esta resposta porque pensei que seria uma analogia divertida (e adequada):

Pense em um objeto com chave como um quadro - negro (com chave) em uma sala de aula contendo um professor (escritor) e muitos alunos (leitores).

Enquanto um professor está escrevendo algo (cadeado exclusivo) no quadro:

  1. Ninguém pode ler, porque ainda está sendo escrito e está bloqueando sua visualização => Se um objeto estiver bloqueado exclusivamente, bloqueios compartilhados não podem ser obtidos .

  2. Outros professores também não vão subir e começar a escrever, ou o quadro torna-se ilegível e confunde os alunos => Se um objeto estiver bloqueado exclusivamente, outros bloqueios exclusivos não podem ser obtidos .

Quando os alunos estão lendo (bloqueios compartilhados) o que está no quadro:

  1. Todos eles podem ler o que está nele, juntos => Vários bloqueios compartilhados podem coexistir .

  2. A professora espera que eles terminem de ler antes de limpar o quadro para escrever mais => Se um ou mais bloqueios compartilhados já existem, bloqueios exclusivos não podem ser obtidos .


2
explicação muito boa. No entanto, o PO questionou sobre a origem das denominações "compartilhadas" e "exclusivas", e não sobre uma explicação dos termos em si.
serhio de

É "Se um ou mais bloqueios compartilhados já existem, bloqueios exclusivos não podem ser obtidos." é verdade? interms de ReentrantReadWriteLock? Achei que o bloqueio de gravação pudesse ser obtido a qualquer momento, caso contrário, a falta de gravação pode ocorrer devido à leitura contínua.
Kanagavelu Sugumar

1
@KanagaveluSugumar, sim, é verdade. Você simplesmente não pode obter um bloqueio de gravação quando outra entidade já possui um bloqueio de leitura no mesmo objeto. Esse é o ponto principal de um bloqueio de leitura e gravação. Se acontecer de você substituir algo enquanto outra pessoa está lendo, o que então essa pessoa lerá? Não sei por que você escolheu escolher um bloqueio "reentrante" de leitura e gravação especificamente, mas a reentrância significa que o proprietário de um bloqueio reentrante pode 'travá-lo ()' novamente e todas as lock()chamadas subsequentes após o primeiro retornará imediatamente e com sucesso. ou seja, você pode bloquear com êxito algo que já possui.
ArjunShankar

2
Você também mencionou que "Achei que o bloqueio de gravação pudesse ser obtido a qualquer momento, caso contrário, a falta de gravação pode acontecer devido à leitura contínua" - isso simplesmente não pode ser. Um bloqueio de gravação não pode ser obtido enquanto alguma outra entidade possui um bloqueio de leitura / gravação. O que pode acontecer é que, se várias entidades já estiverem aguardando para bloquear um objeto, a espera writerterá preferência sobre os leitores em espera quando o bloqueio escolher quem obterá o bloqueio em seguida (quando ele for desbloqueado pelo seu proprietário atual). Isso é sobre política .
ArjunShankar de

Obrigado! Eu escolhi ReentrantReadWriteLock; já que essa é a classe de implementação para ReadWriteLock em java. Então, há algum sinalizador levantado ou mais prioridade definida para dizer que novos threads de leitura devem esperar quando o thread de gravação começar a aguardar? Porque como evitar a privação de thread de gravação por causa da solicitação de leitura contínua?
Kanagavelu Sugumar

33

É muito simples. Os bloqueios de leitura também são conhecidos como bloqueios compartilhados porque mais de um processo pode ler ao mesmo tempo. O objetivo de um bloqueio de leitura é evitar a aquisição de um bloqueio de gravação por outro processo. Por outro lado, um bloqueio de gravação inibe todas as outras operações enquanto uma operação de gravação é concluída, por isso é descrita como exclusiva.

Portanto, um bloqueio de leitura diz "você pode ler agora, mas se quiser escrever, terá que esperar", enquanto um bloqueio de gravação diz "você terá que esperar".


Sei que você está pesquisando para apoiar seus estudos, mas não consigo resistir à vontade de dar uma palestra.

O uso incompetente de travamento é a principal causa de dores de cabeça de desempenho. O uso de um sistema de bloqueio que diferencia os bloqueios de leitura e gravação é um bom começo, mas o design cuidadoso pode, às vezes, eliminar grande parte da necessidade de bloqueio. Por exemplo, o estado da sessão nunca deve ser mantido em uma coleção global por elemento de estado.

Eu realmente vi isso ser feito. É um design atroz, causando boxe e uma mudança em uma coleção para cada última mudança no estado da sessão, acarretando um bloqueio de gravação prolongado. As despesas gerais estavam prejudicando, reduzindo efetivamente o servidor a um comportamento de thread único.

Simplesmente agregar todo o estado da sessão em uma estrutura foi uma grande melhoria. Mudanças no estado da sessão simplesmente mudaram os valores dos membros de uma estrutura de estado da sessão. Como nenhuma outra sessão teve ocasião ou mesmo oportunidade de fazer referência direta ao estado de uma sessão, a única coleção sendo atualizada foi a lista de sessões. Como resultado, o bloqueio era completamente desnecessário durante uma sessão, apenas no início e no final, e a taxa de transferência aumentou por um fator de 3.000.

O outro cenário de bloqueio comum são recursos compartilhados entre threads de um aplicativo de usuário. A maioria das estruturas modernas trata disso usando mensagens em vez de bloqueios; quando você "faz a transição para o thread de interface do usuário", está na verdade enfileirando uma mensagem contendo um ponteiro de função e alguns parâmetros (ou um delegado e um quadro de pilha dependendo da implementação).


6
  • Um bloqueio exclusivo ou de gravação dá a um processo acesso exclusivo para gravar na parte especificada do arquivo. Enquanto um bloqueio de gravação estiver em vigor, nenhum outro processo pode bloquear essa parte do arquivo.

  • Um bloqueio compartilhado ou de leitura proíbe qualquer outro processo de solicitar um bloqueio de gravação na parte especificada do arquivo. No entanto, outros processos podem solicitar bloqueios de leitura.

Mais sobre isso: http://www.gnu.org/software/libc/manual/html_node/File-Locks.html


2

Princípio mesmo no lado do banco de dados. De acordo com a documentação Oracle

O modo de bloqueio exclusivo evita que o recurso associado seja compartilhado. Este modo de bloqueio é obtido para modificar dados. A primeira transação a bloquear um recurso exclusivamente é a única transação que pode alterar o recurso até que o bloqueio exclusivo seja liberado.

O modo de bloqueio de compartilhamento permite que o recurso associado seja compartilhado, dependendo das operações envolvidas. Vários usuários lendo dados podem compartilhar os dados, mantendo bloqueios de compartilhamento para evitar o acesso simultâneo por um gravador (que precisa de um bloqueio exclusivo). Várias transações podem
adquirir bloqueios de compartilhamento no mesmo recurso.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.