Enquanto tentava entender como SubmissionPublisher
( código-fonte no Java SE 10, OpenJDK | docs ), uma nova classe adicionada ao Java SE na versão 9, foi implementada, deparei-me com algumas chamadas de API para as quais VarHandle
eu não tinha conhecimento anteriormente:
fullFence
, acquireFence
, releaseFence
, loadLoadFence
E storeStoreFence
.
Depois de fazer algumas pesquisas, especialmente com relação ao conceito de barreiras / cercas de memória (eu as ouvi anteriormente, sim; mas nunca as usei, portanto, não estava familiarizado com sua semântica), acho que tenho um entendimento básico sobre o que elas servem. . No entanto, como minhas perguntas podem surgir de um equívoco, quero garantir que eu acertei em primeiro lugar:
Barreiras de memória são restrições de reordenação relacionadas às operações de leitura e gravação.
As barreiras de memória podem ser categorizadas em duas categorias principais: barreiras de memória unidirecionais e bidirecionais, dependendo se elas definem restrições nas leituras, gravações ou ambas.
O C ++ suporta uma variedade de barreiras de memória , no entanto, elas não coincidem com as fornecidas por
VarHandle
. No entanto, algumas das barreiras de memória disponíveis emVarHandle
proporcionar efeitos de ordenação que são compatíveis com as suas barreiras de memória correspondentes C ++.#fullFence
é compatível comatomic_thread_fence(memory_order_seq_cst)
#acquireFence
é compatível comatomic_thread_fence(memory_order_acquire)
#releaseFence
é compatível comatomic_thread_fence(memory_order_release)
#loadLoadFence
e#storeStoreFence
não possui contraparte C ++ compatível
A palavra compatível parece ser realmente importante aqui, pois a semântica difere claramente quando se trata de detalhes. Por exemplo, todas as barreiras de C ++ são bidirecionais, enquanto as barreiras de Java não são (necessariamente).
- A maioria das barreiras de memória também tem efeitos de sincronização. Esses dependem especialmente do tipo de barreira usado e das instruções de barreira executadas anteriormente em outros segmentos. Como as implicações completas de uma instrução de barreira são específicas do hardware, continuarei com as barreiras de nível superior (C ++). Em C ++, por exemplo, as alterações feitas antes de uma instrução de barreira de liberação são visíveis para um thread que executa uma instrução de barreira de aquisição .
Minhas suposições estão corretas? Nesse caso, minhas perguntas resultantes são:
As barreiras de memória disponíveis
VarHandle
causam algum tipo de sincronização de memória?Independentemente de causar ou não sincronização de memória, para que podem ser úteis restrições de reordenamento em Java? O Java Memory Model já oferece algumas garantias muito fortes em relação à solicitação quando campos, bloqueios ou
VarHandle
operações voláteis#compareAndSet
estão envolvidos.
Caso você esteja procurando um exemplo: A mencionada acima BufferedSubscription
, uma classe interna de SubmissionPublisher
(fonte vinculada acima), estabeleceu uma barreira completa na linha 1079 (função growAndAdd
; como o site vinculado não suporta identificadores de fragmentos, apenas CTRL + F para isso) ) No entanto, não está claro para mim o que existe.
plain -> opaque -> release/acquire -> volatile (sequential consistency)
.