Breve análise do princípio sincronizado e princípio de realização do mecanismo de notificação de espera no objeto Java

Qual é o mecanismo de notificação de espera na programação simultânea? Resumindo, um thread modifica o valor de um objeto e outro thread percebe a mudança e então realiza a operação correspondente. No blog anterior , o uso de LockSupport e Condition of Java JUC Concurrent Package Components , introduzimos o mecanismo de notificação de espera implementado usando o sincronizador de fila. Neste artigo, introduzimos o mecanismo de notificação de espera de objetos Java implementados usando synchronized, e a espera / notificação relacionada Os métodos estão disponíveis para qualquer objeto Java, porque esses métodos são definidos na superclasse java.lang.Object de todos os objetos. Os métodos e as descrições são mostrados na tabela a seguir:

Nome do método

descrição

esperar()

O encadeamento que chama este método entra no estado WAITING e retorna apenas quando aguarda a notificação de outro encadeamento ou é interrompido. Observe que o bloqueio do objeto será liberado após o método de espera ser chamado

longa espera)

Aguarde um pouco; se não houver notificação, o tempo limite será atingido e retornará. O parâmetro é milissegundos

espere (longo, int)

Controle mais refinado do período de tempo limite, até nanossegundos

notificar ()

Notifica um thread que aguarda o objeto para retornar do método de espera, e a premissa do retorno é que o thread adquiriu o bloqueio do objeto

notificar tudo ()

Notificar todos os threads esperando no objeto

O método acima: um thread A chama o método wait () do objeto O para entrar no estado de espera, e outro thread B chama o método notificar () ou notificarAll () do objeto O, e o thread A recebe a notificação do wait () do objeto O ) O método retorna e executa as operações subsequentes. Este é o mecanismo de notificação de espera de objetos Java. Esses métodos precisam ser usados ​​com synchronized. Primeiro, apresentamos o princípio de implementação de synchronized. A palavra-chave synchronized pode modificar o método ou usá-lo na forma de um bloco sincronizado. Isso garante principalmente que vários threads só possam estar em um método ou bloco de sincronização ao mesmo tempo e garante a visibilidade e exclusividade do acesso do thread às variáveis.

Na introdução anterior ao uso de synchronized, foi introduzido que qualquer objeto tem seu próprio monitor. Quando este objeto é chamado pelo bloco de sincronização ou pelo método de sincronização deste objeto, o thread que executa o método deve primeiro obter o monitor do objeto antes de poder entrar na sincronização. Método de bloqueio ou sincronização, mas não obteve o monitor (execute o método) thread será bloqueado na entrada do bloqueio de sincronização e método de sincronização, entre no estado BLOQUEADO, a figura a seguir descreve o objeto, monitor de objeto, fila de sincronização e A relação entre threads de execução:

 Qualquer acesso de thread a um objeto (o objeto é protegido por synchronized) deve primeiro obter o monitor de objeto. Se a aquisição falhar, o thread entra na fila de sincronização e o status do thread torna-se BLOQUEADO. Quando o predecessor de acessar o Objeto (o encadeamento que adquiriu o bloqueio) libera o bloqueio, a operação de liberação ativa o encadeamento bloqueado na fila de sincronização e o faz tentar novamente a aquisição do monitor. Aqui não está mais introduzindo o uso de sincronizado, você pode consultar a segurança do tópico do blog e o uso de atualização sincronizada e de bloqueio .

Anteriormente, apresentamos a implementação interna de synchronized. A seguir, apresentamos a implementação do mecanismo de notificação de espera para objetos Java. Em comparação com a implementação sincronizada, o mecanismo de notificação de espera é implementado com base na implementação sincronizada e o processo é mais complicado. Vamos primeiro escrever um exemplo de espera por notificação, o código é o seguinte:

public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();
    public static void main(String[] args) throws Exception {
	//等待线程
	Thread waitThread = new Thread(new Wait(), "WaitThread");
	waitThread.start();
	TimeUnit.SECONDS.sleep(1);
	//通知线程
	Thread notifyThread = new Thread(new Notify(), "NotifyThread");
	notifyThread.start();
    }

    static class Wait implements Runnable {
        public void run() {
	    // 加锁,拥有lock的Monitor
	    synchronized (lock) { 
		// 当条件不满足时,继续wait,同时释放了lock的锁
		while (flag) {
		    try {
		        System.out.println("WAITING 线程启动并且执行");
		        //调用wait方法,线程进入WAITING状态
			lock.wait();
		    } catch (InterruptedException e) {
					}
		} // 条件满足时,完成工作
            }
            System.out.println("收到 notify通知,获取对象监视器,继续执行");
        }
    }

    static class Notify implements Runnable {
	public void run() {
	    // 加锁,拥有lock的Monitor
	    synchronized (lock) { 
            // 获取lock的锁,然后进行通知,通知时不会释放lock的锁, 
	    System.out.println("通知线程启动");
	    //通知其他处理WAITING状态的线程
	    lock.notifyAll();
	    flag = false;
	    }
	}
    }
}

A partir do exemplo acima, podemos ver que o mecanismo de espera / notificação de objetos Java conta com o mecanismo de sincronização, cujo objetivo é garantir que o encadeamento de espera possa perceber a modificação da variável feita pelo encadeamento de notificação quando ele retorna do método wait (). No exemplo acima, WaitThread primeiro obtém o bloqueio do objeto e, em seguida, chama o método wait () do objeto, desistindo do bloqueio e entrando no WaitQueue do objeto, entrando no estado de espera. Como WaitThread libera o bloqueio do objeto, NotifyThread subsequentemente adquire o bloqueio do objeto e chama o método notificar () do objeto para mover WaitThread de WaitQueue para SynchronizedQueue. Nesse momento, o estado de WaitThread fica bloqueado. Depois que NotifyThread libera o bloqueio, WaitThread obtém o bloqueio novamente e retorna do método wait () para continuar a execução. A seguir está seu fluxograma de transição de estado:

Acho que você gosta

Origin blog.csdn.net/wk19920726/article/details/108710059
Recomendado
Clasificación