Java finalizar notas de estudo ao bloquear

Um encadeamento pode estar nos quatro estados a seguir:
1: Novo (novo): quando o encadeamento é criado, ele permanecerá neste estado por um curto período de tempo. Nesse ponto, ele alocou os recursos de sistema necessários e executou a inicialização. Neste momento, a thread já está qualificada para o tempo de CPU, e então o agendador irá transformar esta thread em um estado executável ou bloqueado.

2: Pronto (Executável): Neste estado, enquanto o agendador alocar fatias de tempo para threads, as threads podem ser executadas. Em outras palavras, a qualquer momento, o tópico pode ou não ser executado. Desde que o planejador possa alocar fatias de tempo para threads, ele pode ser executado, o que é diferente dos estados morto e bloqueado.

3: Bloqueado: o thread pode ser executado, mas alguma condição o impede de ser executado. Quando um thread está em um estado bloqueado, o agendador irá ignorar o thread e não alocará nenhum tempo de CPU para o thread. Não será possível realizar operações até que o thread entre novamente no estado pronto.

4: Dead (Dead): O encadeamento no estado morto ou encerrado será escalonável quando terminar, e não obterá tempo de CPU, sua tarefa terminou ou não pode mais ser executada, da maneira usual quando a tarefa termina Retorne do método run (), mas o thread da tarefa ainda pode ser interrompido, como você verá.

A entrada no estado de bloqueio pode ter os seguintes motivos:

1: dormir dormir.

2: Suspenda o thread chamando wait (). Até que o encadeamento obtenha notificar () ou notificarAll ().

3: A tarefa está aguardando a conclusão de uma entrada / saída.

4: A tarefa tenta usar outros métodos de controle de sincronização em um objeto, mas o bloqueio do objeto não está disponível porque outra tarefa já adquiriu o bloqueio.

Ao interromper uma tarefa bloqueada, pode ser necessário limpar os recursos. Por causa disso, a interrupção no meio do método run () da tarefa é mais como uma exceção lançada, portanto, exceções são usadas neste tipo de interrupção de exceção em threads java. Portanto, você precisa escrever cuidadosamente as cláusulas try-catch para limpar tudo de maneira adequada.

A classe Thread contém o método Interrupt () , para que você possa interromper a tarefa bloqueada.Este método definirá o status de interrupção do thread. Se um thread estiver bloqueado ou tentando realizar uma operação de bloqueio, chamar este método neste momento lançará uma InterruptedException .
Quando a exceção é lançada ou a tarefa chama o método Thread.interrupt, o status de interrupção é redefinido.
O método Thread.interrupt () fornece uma segunda maneira de sair de run () sem lançar uma exceção. Para chamar Thread.interrupt (), você precisa manter um objeto Thread.

O Executor fornecido pela nova biblioteca de classes atual parece evitar a manipulação direta de objetos Thread.
Se shutdownNow () for chamado no Executor , ele enviará uma chamada interrupt () para todos os threads que iniciar .
Cancelar (booleano) é uma forma de interromper uma única thread iniciada pelo Executor. Neste momento, a tarefa deve ser iniciada pelo método submit () em vez do método execute () .
O método submit () retornará um Future <?> Genérico, no qual o método cancel (booleano) (o parâmetro é verdadeiro) pode ser chamado para encerrar a tarefa .

class SleepBlocked implements Runnable{
    
    
	public void run() {
    
    
		try {
    
    
			TimeUnit.MILLISECONDS.sleep(100);
		}catch(InterruptedException e) {
    
    
			System.out.println("InterruptedException");
		}
		System.out.println("Exiting SleepBlocked.run()");
	}
} 
class IOBlocked implements Runnable{
    
    
	private InputStream in;
    public IOBlocked(InputStream is) {
    
    in=is;}
	@Override
	public void run() {
    
    
		try {
    
    
			System.out.println("Waiting for read():");
			in.read();
		}catch(IOException e) {
    
    
			if(Thread.currentThread().isInterrupted()) {
    
    
				System.out.println("Interrupted from blocked I/O");
			}
			else {
    
    
				throw new RuntimeException(e);
			}
		}
		System.out.println("Exiting IOBlocked.run()");
	}
}
class SynchronizedBlocked implements Runnable{
    
    
	public synchronized void f() {
    
    
		while(true) {
    
    
			Thread.yield();
		}
	}
	public SynchronizedBlocked() {
    
    
		new Thread() {
    
    
			public void run() {
    
    
				f();
			}
		}.start();
	}
	public void run() {
    
    
		System.out.println("Trying to call f()");
		f();
		System.out.println("Exiting SynchronizedBlocked.run()");
	}
}
public class Interrupting {
    
    
	private static ExecutorService exec=Executors.newCachedThreadPool();
	static void test(Runnable r) throws InterruptedException{
    
    
		Future<?> f=exec.submit(r);
		TimeUnit.MILLISECONDS.sleep(100);
		System.out.println("Interrupting "+r.getClass().getName());
		f.cancel(true);
		System.out.println("Interrupting sent to "+r.getClass().getName());
	}
	public static void main(String[] args) throws InterruptedException {
    
    
		// TODO Auto-generated method stub
        test(new SleepBlocked());
        test(new IOBlocked(System.in));
        test(new SynchronizedBlocked());
        TimeUnit.MILLISECONDS.sleep(3);
        System.out.println("Absorbing with System.exit(0)");
        System.exit(0);
	}

}
/*
Exiting SleepBlocked.run()
Interrupting demo.SleepBlocked
Interrupting sent to demo.SleepBlocked
Waiting for read():
Interrupting demo.IOBlocked
Interrupting sent to demo.IOBlocked
Trying to call f()
Interrupting demo.synchronizedBlocked
Interrupting sent to demo.synchronizedBlocked
Absorbing with System.exit(0)
*/

Cada tarefa do programa acima representa um tipo diferente de bloqueio. SleepBlock () é um exemplo de bloqueio interrompível, enquanto IOBlocked e SynchronizedBlocked são exemplos de bloqueio não bloqueado. Portanto, I / O e espera no bloco sincronizado são ininterruptos. Navegar no código pode descobrir que não importa se é I / O ou tentando chamar o método sincronizado, nenhum manipulador InterruptedException é necessário.
Em SynchronizedBlocked, devemos primeiro adquirir o bloqueio, que é obtido criando uma instância da classe Thread anônima, que chama f () para adquirir o bloqueio do objeto primeiro. Como o método f () é um loop infinito e nunca retorna, o bloqueio nunca será liberado. Neste momento, o método Synchronized.run () está tentando adquirir o bloqueio do objeto e bloqueia aguardando a liberação do bloqueio.
Pode-se ver no exemplo de programa acima que você não pode interromper uma thread que está tentando adquirir um bloqueio sincronizado ou tentando realizar uma operação de E / S.

Método de processamento de I / O para este

Quanto à classe nio de I / O de interrupção mais amigável ao usuário, nós a adicionaremos quando terminarmos de aprender.

class BlockedMutex{
    
    
	private Lock lock=new ReentrantLock();
	public BlockedMutex() {
    
    
		lock.lock();
	}
	public void f() {
    
    
		try {
    
    
			lock.lockInterruptibly();
			System.out.println("lock acquired in f()");
		}catch(InterruptedException e) {
    
    
			System.out.println("Interruppted from lock acquisition in f()");
		}
	}
}
class Blocked2 implements Runnable{
    
    
	BlockedMutex blocked=new BlockedMutex();
	public void run() {
    
    
		System.out.println("Waiting for f() in BlockedMutex");
		blocked.f();
		System.out.println("Broken out of blocked call");
	}
}
public class Interrupting2 {
    
    

	public static void main(String[] args) throws InterruptedException {
    
    
		// TODO Auto-generated method stub
        Thread t=new Thread(new Blocked2());
        t.start();
        TimeUnit.MILLISECONDS.sleep(1);
        System.out.println("Issuing t.interrupt()");
        t.interrupt();
	}

}

O programa acima: java SE5 adiciona um recurso que permite que as tarefas bloqueadas no ReentrantLock sejam interrompidas, o que é diferente das tarefas bloqueadas em métodos sincronizados ou seções críticas.

Acho que você gosta

Origin blog.csdn.net/weixin_43916777/article/details/104316678
Recomendado
Clasificación