"Java Concurrency em combate," as notas de estudo (1)

Capítulo Um: Introdução

pontos de conhecimento :

  • Processo é de recursos (CPU, memória, etc.) atribuído à unidade básica
  • Um segmento é a unidade básica de escalonamento de CPU e expedição
  • Um processo que inclui um ou mais segmentos

1, por isso a aplicação precisa de se desenvolver a partir de segmento único para multi-threaded (a partir síncrono para assíncrono)?

  • a utilização de recursos . Às vezes é necessário esperar para operações externas, como entrada e saída, e não pode realizar trabalho valioso enquanto espera. Enquanto espera, para que outros programas irão melhorar a eficiência operacional.
  • Fair . Vários usuários ou programas podem ter igual prioridade nos recursos do sistema. Permita-lhes para compartilhar fatia de tempo computador através de melhores formas mais desejáveis do que os próximos extremidades programa após o início de um programa.
  • Conveniente . Escrever alguns procedimentos, de modo que cada um deles executa uma única tarefa e fazer a coordenação necessária, que é melhor do que escrever um programa para executar todas as tarefas mais fácil e mais satisfatório.

Capítulo II: thread-safe

de um objeto estado é os seus dados . Escrever código thread-safe, em essência, é a gestão do estado visita (estado), e muitas vezes são compartilhadas , a variável estado.

A chamada de partilha , refere-se a uma variável pode ser acedida por vários segmentos; o chamado variável refere-se ao valor da variável pode mudar durante o seu ciclo de vida. segurança de segmentos de nossa discussão parece ser sobre o código, mas nós realmente precisamos fazer, é para proteger os dados em acesso simultâneo não é controlado.

Na ausência de sincronização adequada, se vários segmentos acessar a mesma variável, o programa existe risco. Há três maneiras de corrigi-lo:

  • Faça variáveis ​​não cross-fio compartilhada;
  • Uma variel de estado é imutável; ou
  • acesso síncrono em quaisquer variáveis ​​de estado de tempo.

Thread-safe definição:

Quando vários segmentos acessar uma classe, se não considerar programação alternativa e execução nestes tópicos no ambiente de tempo de execução, e não requer sincronização adicional e o código de chamada não faz outro comportamento coordenação desta classe ainda está correto em seguida, chamar essa classe é thread-safe de.

objetos apátridas são sempre thread-safe.

Tópico insegurança operação complexa

Leia - mudança - write (ler-modificar-escrever)

@NotThreadSafe
public class UnsafeCountingFactorizer implements Servlet {
    private long count = 0;
    public long getCount() { return count; }
    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = factor(i);
        ++count;
        encodeIntoResponse(resp, factors);
    }
}

Verifique o prazo (check-act)

@NotThreadsafe
public class LazyInitRace {
    private Expensive0bject instance = null;
    public ExpensiveObject getInstance() {
        if ( instance == null ) {
            instance = new Expensive0bject();
        }
        return instance;
    }
}

A fim de assegurar, operações de thread-safe "check-run" (como inicialização lenta) e ler - modificar - operações de gravação (como incremento) deve ser atômica. Vamos "corrida de controle" e "Leia - mudança - write" todo o processo de execução de uma operação complexa: A fim de garantir o funcionamento thread-safe devem ser executadas atomicamente.

Na próxima seção, vamos considerar o uso de built-atômicas mecanismos de Java - fechaduras. Agora, vamos corrigir esse problema de outras maneiras - usando as classes thread-safe existentes.

@ThreadSafe
public class CountingFactorizer implements Servlet {
    private final AtomicLong count = new AtomicLong(0);
    public long getCount() { return count.get(); }
    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = factor(i);
        count.incrementAndGet();
        encodeIntoResponse(resp, factors);
    }
}

java.util.concurrent.atomicO pacote inclui variáveis átomos (variável) atómica classes para implementar estados atómicas das referências de objeto de conversão e digitais. Os longtipos alternativos de contra- AtomicLongtipos, podemos garantir que todo o acesso ao estado de balcão são atômica. Contadores são thread-safe.

bloqueio interno

Java fornece um mecanismo atômicas built-in bloqueio forçado: synchronized. Um synchronizedbloco que tem duas partes: o objeto de bloqueio é referenciada, e o bloco de bloqueio de código de protecção.

Cada objecto de Java pode desempenhar um papel bloquear implicitamente para sincronização; estes embutido fechaduras é chamado bloqueio interior (fechaduras intrínsecas) ou um monitor de bloqueio (monitor de bloqueios).

segmento de execução para entrar synchronizede sair através do normal, independentemente do caminho de controle, ou jogado a partir do bloco, as roscas estão a dar-se; irá bloquear automaticamente até que o fecho synchronizedé libertado automaticamente quando o bloco de controlo de bloqueio.

A única maneira de obter dentro da fechadura é: O método de inserção do bloco de sincronização ou proteger o bloqueio interno.

bloqueio interno jogado em Java mutex (bloqueio de exclusão mútua, também chamada de exclusão mútua) papel, o que significa que, no máximo, apenas um thread pode possuir o bloqueio, quando a rosca Um está tentando solicitar um B ocupada bloqueio, rosca Um imperativo esperar ou bloco até B libera-lo. Se B não libera o bloqueio, A vai esperar para sempre.

Re-entrada (reentrância)

Quando um segmento solicita outro segmento já tem um bloqueio, o segmento solicitante será bloqueado. No entanto, bloqueio interno é re-introduzido, de modo que o fio em seu próprio tempo tentando obter a posse da fechadura, o pedido será bem sucedido.

meios de reentrada que o pedido é baseado em " por thread (por thread)", em vez de " por chamada (por invocação)" é.

Ela é alcançada por reentrada a uma contagem pedido associado a cada bloqueio (contagem de aquisição) e um fio possui. Quando a contagem é 0, que o bloqueio está desocupado.

Quando um segmento solicita o bloqueio desocupado, a JVM gravação bloqueio ocupante, ea contagem do pedido é definido como 1. Se o mesmo segmento solicita novamente o bloqueio contagem é incrementada; blocos de sincronização cada segurando saídas de rosca, o valor do contador é diminuído. Até o contador chegar a zero, o bloqueio será liberado.

/**
*	如果该锁不是可重入的,代码将死锁
*/
public class Widget {
	public synchronized void doSomething() {
		...
	}
}
public class LoggingWidget extends Widget {
	@Override
	public synchronized void doSomething() {
		super.doSomething();
	}
}

Para cada variável de estado variável pode ser acessada por vários segmentos, se todo o acesso que tem desempenhado na implementação da linha com um bloqueio, caso em que, nós chamamos esta variável é a proteção de bloqueio.

Cada variável variáveis ​​compartilhadas precisa bloquear protegido por apenas uma determinada.

Ajuste synchronizedo tamanho do bloco, de modo a alcançar um equilíbrio entre segurança e desempenho.

Cálculo ou algumas operações demoradas, como o console ou uma rede de I / O, é difícil rapidamente. Não bloquear posse durante a execução dessas operações.

Publicado 107 artigos originais · Louvor obteve 88 · vista 260 000 +

Acho que você gosta

Origin blog.csdn.net/Code_shadow/article/details/104275669
Recomendado
Clasificación