introdução
Java fornece o pacote java.util.Concurrent.atomic desde JDK1.5, que facilita os programadores a executar operações atômicas sem bloqueios em um ambiente multithread. A camada subjacente das variáveis atômicas usa instruções atômicas fornecidas pelo processador, mas diferentes arquiteturas da CPU podem fornecer instruções atômicas diferentes e também podem exigir alguma forma de bloqueio interno; portanto, esse método não pode garantir absolutamente que o encadeamento não esteja bloqueado.
Introdução ao pacote atômico
Existem 12 classes no pacote atômico e quatro métodos de atualização atômica são: Tipos básicos de atualização atômica, matrizes de atualização atômica, referências de atualização atômica e campos de atualização atômica. As classes no pacote atômico são basicamente classes embrulhadas implementadas usando inseguro.
Atualização atômica Classe de tipo básico
Para atualizar os tipos básicos por meio de métodos atômicos, o pacote atômico fornece as três classes a seguir:
AtomicBoolean: Atomic atualiza o tipo booleano.
AtomicInteger: Atualização atômica Inteiro.
Atomiclong: Atualização atômica Inteiro longo.
Os métodos comuns do AtomicInteger são os seguintes:
int addandget (int delta): adiciona o valor de entrada ao valor na instância (valor em atomicinteger) de maneira atômica e retorna o resultado
Boolean ComparaNDSet (int espera, int update): Se o valor de entrada for igual ao valor esperado, defina o valor no valor de entrada atomicamente.
int getAndIncrement (): adiciona o valor atual a 1 atomicamente. NOTA: O valor retornado aqui está o valor antes do auto -increment.
Void Lazyset (int newValue): Ele será definido como NewValue. Depois de usar o Lazyset para definir o valor, outros threads ainda poderão ler o valor antigo Int GetandSet (int newValue): ele é definido como o valor do novoValue de maneira atômica e retorna o valor antigo.
O código de exemplo atomicinteger é o seguinte:
importar java.util.Concurrent.atomic.atomicinteger; public class atomicintegerestest {estático atomicinteger ai = new atomicinteger (1); public static void main (string [] args) {System.out.println (ai.getAndIrcrement ();;Saída
12
Sobremesa depois do jantar
O pacote atômico fornece três tipos básicos de atualizações atômicas, mas os tipos básicos Java incluem char, float e duplo. Portanto, a questão é: como atualizar outros tipos básicos de átomos? As classes no pacote atômico são basicamente implementadas usando inseguro. Vamos dar uma olhada no código -fonte de inseguro. Descobrimos que o Inseguro fornece apenas três métodos CAS, comparandswapobject, comparaandswapint e comparandswaplong. Em seguida, observe o código -fonte AtomicBoolean. Descobrimos que ele primeiro converte booleano em um número inteiro e depois usa o Comparanswapint para CAS, então a atualização atômica dupla também pode ser implementada usando idéias semelhantes.
Classe de matriz de atualização atômica
O pacote atômico fornece as três classes a seguir:
AtomicintegerRay: atualiza atomicamente os elementos em uma matriz inteira.
AtomiclonGray: Atomic atualiza elementos em matrizes longas.
AtomicReferenceArray: Atomic atualiza elementos na matriz do tipo de referência.
A classe AtomicintegerRay fornece principalmente atômico para atualizar os números inteiros na matriz. Os métodos comumente usados são os seguintes
int addandget (int i, int delta): adiciona o valor de entrada atomicamente ao índice de elementos I na matriz.
Boolean ComparaNDSet (int i, int espera, int update): se o valor atual for igual ao valor esperado, o elemento na posição da matriz I é atomicamente definido como o valor de atualização.
O código de exemplo é o seguinte:
public class atomicintegerRArraytest {static int [] value = new int [] {1, 2}; estático atomicintegerRaRray ai = new atomicintegerRaRray (value); public static void main (string [] args) {ai.getAndSet (0, 0, 3); System.out.println (ai.get (0)); System.out.println (valor [0]);}}Saída
31
O que você precisa observar na classe AtomicintegerRray é que o valor da matriz é passado através do método do construtor e, em seguida, o atomicintegerRaypray copiará a matriz atual uma cópia; portanto, quando atomicintegerRray modificar os elementos da matriz interna, ela não afetará a matriz passada.
Tipo de referência de atualização atômica
O AtomicInteger, que é um tipo básico, pode atualizar apenas uma variável. Se você deseja atualizar várias variáveis atomicamente, precisará usar esse átomo para atualizar a classe fornecida pelo tipo de referência. O pacote atômico fornece as três classes a seguir:
AtomicReference: Atomic atualiza o tipo de referência.
AtomicReferenceFieldUpDater: Atomic atualiza campos no tipo de referência.
AtomicmarkableReference: Atomic atualiza o tipo de referência com bits de marcador. Você pode atualizar atomicamente um bit e tipo de tag do tipo booleano. O método de construção é atomicmarkableReference (V InitialRef, Boolean InitialMark)
O código para o uso de atômico é o seguinte:
public class AtomicReferenceTest {public static atomicReference <suser> atomicUserRef = new atomicreference </user> <suser> (); public static void main (string [] args) {user user = userUSer ("sHinichi", shinichi; atomicUserref.set (user); userTUSTERSTERSETERATERA ("USERAUSTER (" shinichi ", shinichi, shinichi (atomicUserRef.set); usuário; UserTUSTERSETERATERSTERA (" Usuário ", shinichi (shinichi); atomiSerf.Set; updateUser); System.out.println (atomicUserRef.get (). getName ()); system.out.println (atomicUserRef.get (). getold ());} classe estática user {private string; private int antigo; public user (string name, antigo) {this.name = name; getold () {return Old;}}}Saída
Shinichi17
Classe de campo de atualização atômica
Se precisarmos apenas de um determinado campo em uma determinada classe, precisamos usar o Atomic para atualizar a classe de campo. O pacote atômico fornece as três classes a seguir:
AtomicIntegerFieldUpDater: Um atualizador para campos que atualizam atomicamente os números inteiros.
AtomiclongfieldUpdater: um atualizador para atualizações atômicas campos inteiros longos.
AtomicstampedReference: Atomic atualiza o tipo de referência com um número de versão. Essa classe associa valores inteiros às referências e pode ser usada para mais dados atômicos e de versão, que podem resolver os problemas do ABA que podem surgir ao usar CAS para atualizações atômicas.
As classes de campo de atualização atômica são classes abstratas e, cada vez que são usadas, elas devem usar o método estático newupdater para criar um atualizador. O modificador público volátil deve ser usado para campos da classe de atualização atômica.
A primeira etapa é que, como as classes de campo de atualização atômica são classes abstratas, cada vez que você usa o método estático atomicintegerfieldupdater.newupdater, você deve criar um atualizador e precisar definir as classes e propriedades que deseja atualizar. A segunda etapa é atualizar os campos (propriedades) da classe devem usar o modificador público volátil (private volátil int antigo)
O código de exemplo do atomicintegerfieldUpdater é o seguinte:
classe pública atomicintegerfieldUpdatertest {private estático atomicintegerfieldUpdater <suser> a = atomicintegerfieldupdater.newupdater (user.class, "antigo"); public static void main (string [] args) {user conan = novo usuário ("conan", 10); system.out.println (a.GetAndIncrement (Conan)); System.out.println (a.get (conan));} public static class User {private string name; public volatile int antigo; public string (string name, Int Antd) {this.name = this.s.s.) {}} {{{{{{{Saída
1011
Resumir
O exposto acima é o conteúdo inteiro deste artigo sobre a introdução e uso do pacote atômico multi-thread Java. Espero que seja útil para todos. Amigos interessados podem continuar se referindo a este site:
Introdução ao método de escrever modelo de consumidor de produção sob diferentes condições no Java Multithreading
Java Multithreaded Programming Syncronizer Future e FutureTask Parsing and Code Exemplos
Uma explicação detalhada da trava de exibição com vários threads java e bloqueio embutido
Se houver alguma falha, deixe uma mensagem para apontá -la.