Coleções, Genéricos, Threads Marco Antonio. Collection Principais métodos da interface Collection.

Slides:



Advertisements
Apresentações semelhantes
Programação em Java Prof. Maurício Braga
Advertisements

Estruturas de Repetição
Eventos Marco Antonio, Arquiteto de Software – TJDF Novembro/2005
Classes Abstratas e Interfaces
Reflexão Marco Antonio Arquiteto de Software Novembro/2007.
Modificadores Marco Antonio, Arquiteto de Software – TJDF Atualizado em Novembro/2008.
Utilitários Marco Antonio. Enum Como o nome sugere, é uma enumeração de opções para uma determinada situação A principal vantagem é limitar as opções.
Collections Marco Antonio, Arquiteto de Software – TJDF Atualizado Dezembro/2008.
Modificadores Marco Antonio. Introdução Em todas as linguagens de programação o acesso a classes/métodos deve seguir algumas regras.
Entrada e Saída Marco Antonio Arquiteto de Software Dezembro/2007.
Java Básico Orientação a Objeto Marco Antonio Software Architect Fev/2008.
Tratamento de Exceções
Projeto de Sistemas de Software Trabalho de Padrões de Projeto
Programação Básica em Java
Walfredo Cirne walfredo.dsc.ufpb.br
Programação Concorrente
Wagner Santos C. de Jesus
7 Abstração Genérica Unidades genéricas e instanciação.
JAVA ENUMS © 2009 by Jorge L. de Souza Leão março de 2009 PEE - COPPE/UFRJ.
Classes e objetos Arrays e Sobrecarga
Estrutura de Dados em Java
O Mecanismo de Threads em Java 2. Criar uma classe herdeira da super classe Thread public class minhaThread extends Thread{ public class minhaThread extends.
Concorrência em Java Threads em Java.
Threads: Introdução e Implementação
Tipos Agregados Homogêneos e Listas
Unidade I: “Dê um mergulho rápido”
Programação Orientada a Objetos com Java
Professor: Hyggo Almeida
JAVA Linguagem Ambiente de Desenvolvimento
Hashing - Espalhamento
Programação I Aula 2 (Métodos)
Chamada Remota de Procedimentos
OPERADORESOPERADORES SCJP – Otimize-TI. Operadores Java Resultado: Maioria das operações é um booleano ou numérico. Não podem ser sobrecarregados (Existem.
1 Mobilidade de Código com μcode Projeto Giga Alexandre Lages
Professora Lucélia Oliveira
Programação Orientada a Objetos: Reuso
Pilhas Profa. Nádia Félix.
Curso de Aprendizado Industrial Desenvolvedor WEB Disciplina: Programação Orientada a Objetos I Professora: Cheli Mendes Costa This.
Garbage Collection O que é Garbage Collector? É o coletor de lixo que é utilizado pela JVM para a limpeza da memória.
LPII Professora Lucélia. Pacotes Um pacote em Java é um diretório onde ficam armazenadas uma ou mais classes. Geralmente as classes com a mesma afinidade.
Concorrência e thread Petrônio Júnior(pglj) Márcio Neves(mmn2)
Listas Simplesmente Encadeadas
Wagner Santos C. de Jesus
Implementação Orientada a Objetos – Aula 03
Tratamento de Exceções
Linguagem de Programação C#
Programação Orientada a Objetos - Java
Programação I Aula 3 (Entrada de Dados) Prof. Gilberto Irajá Müller Última atualização 11/3/2009.
Introdução às Java Threads
Orientação a Objetos usando Java
Java Kickstart, day 2 Semelhanças com linguagem C.
Aula Prática 4 Monitoria IP/CC (~if669).
Implementação Orientada a Objetos – Aula 05 Construtores e sobrecarga de métodos Prof. Danielle Martin Universidade de Mogi das Cruzes
Polimorfismo.
Curso de Linguagem Java
1 Marcio de Carvalho Victorino JAVA. 2 Declaração de Atributos [ ] [transient] [volatile] [static] [final] ; controle de acesso –public, package (default),
Exceções Suzana Fragoso (smpf) Adaptado do material de Guilherme Carvalho (gvc)
Programação II Prof. Mateus Raeder Universidade do Vale do Rio dos Sinos - São Leopoldo -
Implementação Orientada a Objetos – Aula 06 Conversão de tipos e métodos estáticos Prof. Danielle Martin Universidade de Mogi das Cruzes
JAVA Sintaxe.
Certificação Marco Antonio. Introdução A compreensão desse capítulo é muito importante pois trata de um assunto essencial em qualquer linguagem de programação,
Coleções em Java - Parte 2
Copyright 1998, Departamento de Informática da UFPE. Todos os direitos reservados sob a legislação em vigor. Variáveis e métodos estáticos, Passagem de.
Socket em Java.
POO - I PROF.: JEAN CARLO MENDES
Coleções em Java (Parte 1)
Java Como Programar, 8/E Deitel/Deitel, 8e. Java – Como programar Copyright © 2010 Pearson Education Slide 1.
CURSO JAVA BÁSICO Módulo 9 – slide 1 Módulo 10 Threads.
Capítulo 4. Conjuntos  Introdução  Principais operações de conjuntos  Principais interfaces de conjuntos  A interface Collection  A interface Iterator.
ProgramaçãoConcorrente Glêdson Elias
Transcrição da apresentação:

Coleções, Genéricos, Threads Marco Antonio

Collection Principais métodos da interface Collection.

Map Principais métodos da interface Map.

Hierarquia de Collecion

Ordenação Uma classe é ordenada se pode ser iterada pelos seus elementos em uma ordem específica, através de um índice ou por exemplo pela ordem de inserção.

Classificação Uma classe classificada, quando seus elementos estão classificados por algum critério, como por exemplo, em ordem alfabética, crescente ou cronológica etc. Toda classe classificada é ordenada, já uma classe ordenada pode não ser classificada.

List As classes que implementam a interface List, relevam o índice, com isso podemos inserir um item no meio de uma lista. As classes que implementam a interface List são ordenadas por meio de um índice, isso permite o acesso a um elemento que se encontra no meio da lista, através de seu índice. É uma espécie de sequência para armazenamento de objetos.

List O que precisamos saber é que o índice em uma lista é relevante, toda lista é ordenada, ou seja, podemos iterar em uma ordem especifica, seja ela pela ordem de inserção ou pela ordem do índice. Lista não é classificada.

Características das implementações

Raw types Quando um tipo genérico (como uma coleção) é usado sem o parâmetro, chamamos de raw types. A utilização de raw types não é recomendada, mas é essencial para manter compatibilidade com código legado. Em função disso aparece ao lado da coleção um warning indicando que você não está utilizando o parâmetro de tipo. Para evitar esse warning, utilize a sintaxe logo public class TesteColecaoSemGenericos { {código da classe} }

Coleções sem genéricos Apesar de nossa coleção ter apenas um tipo de classe, para recuperarmos os objetos precisamos fazer um cast. Funciona perfeitamente, mas ainda pode ser melhorado.

Finalmente, coleções com genéricos Com essa sintaxe, não precisamos mais fazer cast. –Collection lista = new ArrayList (); Uma consequência direta da aplicação de genéricos na nossa coleção é que restringimos a adição de objetos somente do tipo Pessoa.

TesteColecaoComGenericos package com.javabasico.genericos; import java.util.*; public class TesteColecaoComGenericos { public static void main(String[] args) { Pessoa p1 = new Pessoa(); p1.setNome("Marco"); Pessoa p2 = new Pessoa(); p2.setNome("Diego"); 1. Collection lista = new ArrayList (); lista.add(p1); lista.add(p2); 2. Iterator ite = lista.iterator(); 3. while (ite.hasNext()) { 4. Pessoa pessoa = ite.next(); }

Tipos parametrizados 1.Declaração do tipo parametrizado da coleção. 2.Declaração do tipo parametrizado do iterator. 3.Loop normal (while). 4.Não precisa mais de conversão, o compilador já sabe que o objeto é do tipo Pessoa. Nem mesmo aceitaria outro tipo de classe.

TesteColecaoComGenericos package com.javabasico.genericos; import java.util.*; public class TesteColecaoComGenericos { public static void main(String[] args) { Pessoa p1 = new Pessoa(); p1.setNome("Marco"); Pessoa p2 = new Pessoa(); p2.setNome("Diego"); Collection lista = new ArrayList (); lista.add(p1); lista.add(p2); 1. for(Pessoa p : lista){ 2. System.out.println(p.getNome()); }

foreach Melhoramento do for tradicional. Não é mais necessário utilizar o iterator. 1.Para cada Pessoa dentro da lista... 2.Imprime o nome.

CaixaDeObjeto sem genéricos Vamos dar uma olhada em um exemplo de classe que utiliza Object, ou seja, não utiliza tipos parametrizados.

CaixaDeObjeto package com.javabasico.genericos; public class CaixaDeObjeto { private Object objeto; public void adiciona(Object objetoAdicionado) { objeto = objetoAdicionado; } public Object recuperaObjeto() { return objeto; }

Conversão obrigatória Sem a utilização de genéricos precisamos sempre fazer conversões. –Integer valorRecuperado = (Integer) caixa.recuperaObjeto(); Não existe validação nenhuma em tempo de compilação já que a conversão é forçada.

TesteCaixaDeObjeto package com.javabasico.genericos; public class TesteCaixaDeObjeto { public static void main(String[] args) { CaixaDeObjeto caixa = new CaixaDeObjeto(); caixa.adiciona(new Integer(10)); Integer valorRecuperado = (Integer) caixa.recuperaObjeto(); System.out.println("Valor integer: " + valorRecuperado); }

Erro de conversão Nada impede o programador de converter para um tipo errado. Infelizmente esse problema só será descoberto em tempo de execução.

TesteCaixaDeObjeto package com.javabasico.genericos; public class TesteCaixaDeObjeto { public static void main(String[] args) { CaixaDeObjeto caixa = new CaixaDeObjeto(); caixa.adiciona(new Integer(10)); String valorRecuperado = (String) caixa.recuperaObjeto(); System.out.println("Valor integer: " + valorRecuperado); }

Mensagem de erro A exceção lançada quando a conversão não pode ser feita é essa a seguir. Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at com.javabasico.genericos.TesteCaixaDeObjeto.main(TesteCaixaDeObjeto.java:7)‏

Tipo parametrizado Vamos atualizar nossa caixa de objetos com um tipo parametrizado. Esse tipo (T) será informado quando criarmos um objeto do tipo CaixaDeObjeto, como uma variável. A mesma técnica pode ser aplicada a interfaces ou métodos.

CaixaDeObjeto package com.javabasico.genericos; 1. public class CaixaDeObjeto { 2. private T objeto; 3. public void adiciona(T objetoAdicionado) { objeto = objetoAdicionado; } 4. public T recuperaObjeto() { return objeto; }

CaixaDeObjeto Declaração do tipo parametrizado. A variável objeto agora é do tipo parametrizado. Esse tipo será indicado mais adiante. O método adiciona só permite que você utilize o tipo T. Recupera o objeto convertido para o tipo T.

Testando Quando criamos um objeto do tipo CaixaDeObjeto devemos informar o tipo, conforme a sintaxe. A partir desse momento, não será mais necessário fazer cast.

TesteCaixaDeObjeto package com.javabasico.genericos; public class TesteCaixaDeObjeto { public static void main(String[] args) { 1. CaixaDeObjeto caixa = new CaixaDeObjeto (); caixa.adiciona(new Integer(10)); System.out.println("Valor integer: " + caixa.recuperaObjeto()); }

TesteCaixaDeObjeto 1.Agora parametrizamos a caixa de objetos. Essa caixa de objetos só aceitará objetos do tipo Integer. Qualquer outro tipo de dado será considerado como erro pelo compilador.

Outros tipos de objetos Vamos criar mais uma caixa de objetos parametrizada para o tipo Pessoa.

TesteCaixaDeObjeto package com.javabasico.genericos; public class TesteCaixaDeObjeto { public static void main(String[] args) { CaixaDeObjeto caixa = new CaixaDeObjeto (); caixa.adiciona(new Integer(10)); System.out.println("Valor integer: " + caixa.recuperaObjeto()); CaixaDeObjeto caixaPessoa = new CaixaDeObjeto (); Pessoa pessoa = new Pessoa(); pessoa.setNome("Marco"); caixaPessoa.adiciona(pessoa); System.out.println("Nome: " + caixaPessoa.recuperaObjeto().getNome()); }

Nomenclatura (apenas sugerida)‏ E - Elemento (usado extensivamente no Java Collections Framework) K - Key N - Number T – Type (Classe) V - Value S,U,V etc. - 2nd, 3rd, 4th types

Mais tipos parametrizados Com o próximo exemplo você pode ver que métodos também aceitam tipos parametrizados.

CaixaDeObjeto package com.javabasico.genericos; public class CaixaDeObjeto { private T objeto; public void adiciona(T objetoAdicionado) { objeto = objetoAdicionado; } public T recuperaObjeto() { return objeto; } public void verifica(U u) { System.out.println("T: " + objeto.getClass().getName()); System.out.println("U: " + u.getClass().getName()); }

TesteCaixaDeObjetoInspecao package com.javabasico.genericos; public class TesteCaixaDeObjetoInspecao { public static void main(String[] args) { CaixaDeObjeto caixa = new CaixaDeObjeto (); caixa.adiciona(new Integer(10)); caixa.verifica(new Pessoa()); caixa.verifica(new String("Alguma frase")); }

Memory import java.util.Date; public class Memory { public static void main(String[] args) { Runtime rt = Runtime.getRuntime(); System.out.println("Memoria total: " + rt.totalMemory()); System.out.println("Memoria Antes: " + rt.freeMemory()); Date d = null; String s = null; for (int i = 0; i < 50000; i++) { d = new Date(); d = null; s = "TEsdfafsadfjasdkfajdçfas"; s = null; } System.out.println("Memoria Depois: " + rt.freeMemory()); rt.gc(); System.out.println("Memoria Final: " + rt.freeMemory()); }

Threads Também chamados de segmentos.

Execucao public class Execucao { public static void main(String[] args) { Proc p = new Proc(); Thread t = new Thread(p); t.start(); while (true) { System.out.println(Thread.currentThread().getName() + " executando"); } class Proc implements Runnable { public void run() { while (true) { System.out.println(Thread.currentThread().getName() + " executando"); }

TesteThread public class TesteThread { public static void main(String[] args) { Counter ct = new Counter(); ct.start(); System.out.println("The thread has been started"); } class Counter extends Thread { public void run() { for (int i = 1; i <= 50; i++) { System.out.println("Count: " + i); }

TesteThread public class TesteThread { public static void main(String[] args) { Counter ct = new Counter(); ct.run(); System.out.println("The thread has been started"); } class Counter extends Thread { public void run() { for (int i = 1; i <= 5; i++) { System.out.println("Count: " + i); }

MultiplasThreads public class MultiplasThreads { public static void main(String[] args) { System.out.println("The main thread of execution started"); RunCounter1 rct1 = new RunCounter1("First Thread"); RunCounter1 rct2 = new RunCounter1("Second Thread"); RunCounter1 rct3 = new RunCounter1("Third Thread"); } class RunCounter1 implements Runnable { Thread myThread; RunCounter1(String name) { myThread = new Thread(this, name); myThread.start(); } public void run() { for (int i = 1; i <= 5; i++) { System.out.println("Thread: " + myThread.getName() + " Count: " + i); }

O método start Quando o método start é chamado a thread não roda imediatamente. Ela vai para o scheduler.

Estados Novo - estado que uma thread fica no momento de sua instanciação, antes da chamada do método start(); Executável - estado em que a thread fica disponível para ser executada e no aguardo do escalonador de thread, esperando a sua vez de se executar; Execução - Momento em que a thread está executando, está operando; Espera/Bloqueio/Suspensão - esse estado pode ser dar por inúmeros motivos. –Uma thread em sua execução pode se bloquear porque algum recurso ou objeto não está disponível, por isso seu estado pode ficar bloqueado, até que esse recurso/objeto esteja disponível novamente assim seu estado torna-se executável, ou então, uma thread pode ficar suspensa porque o programador definiu um tempo de espera, assim que esse tempo expirar essa thread volta ao estado executável para continuar seus serviços; Inativo - a partir do momento em que o método run() foi concluído, a thread se tornará inativa, porém ainda existirá o objeto na memória, somente não como uma linha de execução, e não poderá novamente ser iniciada, ou seja, qualquer tentativa de chamada do método start() após a conclusão do métodos run(), uma exceção será lançada;

TesteRunnable public class TesteRunnable { public static void main(String[] args) { RunCounter rct = new RunCounter(); Thread th = new Thread(rct); th.start(); System.out.println("Thread já iniciada"); th.start(); }

Métodos run() - é o código que a thread executará. start() - sinaliza à JVM que a thread pode ser executada, mas saiba que essa execução não é garantida quando esse método é chamado, e isso pode depender da JVM. isAlive() - volta true se a thread está sendo executada e ainda não terminou. sleep() - suspende a execução da thread por um tempo determinado; yield() - torna o estado de uma thread executável para que thread com prioridades equivalentes possam ser processadas; currentThread() - é um método estático da classe Thread que volta qual a thread que está sendo executada. getName() - volta o nome da Thread, você pode especificar o nome de uma Thread com o método setName() ou na construção da mesma, pois existe os construtores sobrecarregados.

ExemploContador public class ExemploContador { public static void main(String args[]) { ContadorThread c1 = new ContadorThread(); c1.setQtde(10); c1.setName("t001"); c1.start(); ContadorThread c2 = new ContadorThread(); c2.setQtde(15); c2.setName("t002"); c2.start(); }

Cont... class ContadorThread extends Thread { private int qtde = 0; public void run() { for (int i = 0; i <= 100; i++) { if ((i % qtde) == 0) { System.out.println(Thread.currentThread().getName() + "> " + i); } try { sleep(50); } catch (InterruptedException ex) { } public void setQtde(int value) { this.qtde = value; if (this.qtde == 0) this.qtde = 10; }

yield Uma chamada a yield (Thread.yield()) coloca a thread de volta no estado de executável, permitindo que outras threads com a mesma prioridade (ou maior) possam executar. Esse método se propõe a isso. Mas não garante que o comportamento ocorra. Somente pára a execução se outra estiver pronta para executar.

sleep Coloca a thread em espera. Após o período de sleep acabar, a thread volta para o estado de executável: não entra imediamente em execução. Pára a execução em todos os casos.

wait Usado em blocos sincronizados. Pára a execução até ser notificado por outra thread para retornar.

notify Acorda uma thread que está na fila do escalonador. Se essa thread estiver pronta muda o seu estado para executável. notifyAll() acorda todas as threads em estado de aguardando. wait(), notify() e notifyAll() devem ser usados em blocos sincronizados e são implementados em Object.

ClienteSocket import java.io.*; import java.net.*; public class ClienteSocket { public void leDados() { try { Socket clientSock = new Socket(" ", 11000); InputStream in = clientSock.getInputStream(); int len = 0; BufferedOutputStream outFile = new BufferedOutputStream( new FileOutputStream("response.txt")); byte buf[] = new byte[256]; while ((len = in.read(buf)) != -1) { outFile.write(buf, 0, len); } } catch (IOException e) { e.printStackTrace(); }

Block A thread está bloqueada no método read. Operações de IO colocar a thread naturalmente em block.

Questões Quais métodos são usados para executar comunicação entre threads? A. yield()‏ B. sleep(…)‏ C. notify()‏ D. wait()‏

Questões Quais desses métodos estão definidos em Object? A. yield()‏ B. sleep(…)‏ C. run()‏ D. wait()‏ E. notify()‏

QuestaoThread public class QuestaoThread { public static void main(String[] args) { CounterT ct = new CounterT(); ct.start(); System.out.println("The thread has been started"); } class CounterT extends Thread { protected void run() { System.out.println("Hello"); } Quais a saída? The thread has been started. / Hello Hello / The thread has been started. Qualquer das anteriores Erro na linha 9

Questões Quais declarações são verdadeiras sobre o método wait()? A. Uma thread chama wait() para parar temporariamente a execução a execução de outras threads. B. Quando uma thread executa wait(), ela pára sua execução temporariamente. C. Uma chamada a wait() pára a execução da aplicação. D. wait() pertence à classe Object. E. wait() pertence à classe Thread.

Veja o código public class ThreadOrder { static int count = 0; public static void main(String[] args) { CounterO ct = new CounterO(); TrackerO trk1 = new TrackerO(ct, "thread one"); TrackerO trk2 = new TrackerO(ct, "thread two"); trk1.start(); trk2.start(); } class TrackerO extends Thread { CounterO ct; String message; TrackerO(CounterO ct, String msg) { this.ct = ct; message = msg; } public void run() { System.out.println(message); } class CounterO { private int count = 0; public int nextCounter() { synchronized (this) { count++; return count; }

Questão thread one / thread two thread two / thread one Às vezes a primeira alternativa, outras a segunda. Exceção na linha 8.

Questão O que acontece quando uma thread tem o seguinte bloco de código em seu método run? –sleep(500); 1.A execução pára e reinicia 500ms depois. 2.A execução pára e reinicia não antes que 500ms. 3.Erro de compilação. Você não pode chamar o método sleep. 4.Erro de compilação porque sleep não permite argumentos.

notify Uma thread thr está aguardando entre outras para ser executada. Como você pode usar notify() para tirar thr do estado de aguardando? Execute thr.notify() de um bloco de código sincronizado. Execute notify(thr) de um bloco de código sincronizado. Com notify você não pode especificar qual thread seria retirada do estado de aguardando.

Questões Quais desses métodos garantem que uma thread será colocada fora do estado de executando? A. wait()‏ B. yield()‏ C. sleep(500)‏ D. kill()‏ E. notify()‏

Questão Quais dos seguintes são construtores válidos para Thread()? A. Thread()‏ B. Thread(int millisec)‏ C. Thread(Runnable r)‏ D. Thread(Runnable r, String name)‏ E. Thread(int priority)‏

Questões Quais desses métodos são definidos na classe Thread? A. yield()‏ B. sleep(…)‏ C. run()‏ D. wait()‏ E. notify()‏

Exemplos Situações um pouco mais complexas.

TesteProduto public class TesteProduto { public static void main(String[] args) { Produto p = new Produto(5); Thread[] t = new Thread[15]; for (int i = 0; i < t.length; i++) { t[i] = new Thread(p); t[i].setName("Cliente: " + i); t[i].start(); } public class Produto implements Runnable { private int estoque = 5; public void run() { try { for (int i = 0; i < 2; i++) { efetuarPedido(); } } catch (Exception ex) { }

Cont... public void efetuarPedido() { try { if (this.estoque > 0) { System.out.println("Pedido faturado para o cliente " + Thread.currentThread().getName()); Thread.sleep(250); this.estoque--; } else { System.out.println("Não tem estoque para o cliente " + Thread.currentThread().getName()); } } catch (Exception ex) { } public Produto(int value) { this.estoque = value; }

Sincronização Mude o método efetuarPedido para: –public synchronized efetuarPedido

InteraThread import java.io.*; public class InteraThread { public static void main(String[] args) { try { Arquivo arq = new Arquivo(new File("saida.txt")); Thread[] a = new Thread[2]; for (int i=0; i < a.length; i++) { a[i] = new Thread(new Leitura(arq)); a[i].setName( ""+i); a[i].start(); } Thread b = new Thread( new Gravacao(arq) ); b.start(); b.join(); System.out.println("Processo finalizado..."); } catch (Exception ex) {} }

Gravacao class Gravacao implements Runnable { Arquivo arq; public Gravacao(Arquivo value) { arq = value; } public void run() { arq.gravar(); } class Leitura implements Runnable { Arquivo arq; public Leitura(Arquivo value) { arq = value; } public void run() { arq.ler(); }

Arquivo class Arquivo { File file; public Arquivo(File value) { file = value; } synchronized public void ler() { try { if (!file.exists()){ wait(); } System.out.print( "thread# "+Thread.currentThread().getName() + ">>> "); if (file.exists()){ FileInputStream fis = new FileInputStream(file); int in; while ((in=fis.read())!=-1) { System.out.print((char)in); } fis.close(); } catch (Exception e) { e.printStackTrace(); }

Cont... synchronized public void gravar() { try { if (!file.exists()){ FileOutputStream fos = new FileOutputStream(file); for (int i=0; i < 5; i++) { fos.write( ("linha "+i).getBytes() ); } fos.write("\n".getBytes()); fos.close(); System.out.print("Entrou no notify"); notify(); notity(); //ou notifyAll(); } catch (Exception e) { e.printStackTrace(); }

O código dispara 10 threads para leitura de um arquivo que nem foi criado. Dessa forma, todo mundo fica esperando até que esse arquivo seja criado. Uma vez criado o arquivo, a threads saem do estado wait e podem ler do disco.

TesteDeadLock public class TesteDeadLock { public static void main(String[] args) { Object obj1 = "objectA"; Object obj2 = "objectB"; DeadLock t1 = new DeadLock(obj1, obj2); DeadLock t2 = new DeadLock(obj2, obj1); t1.start(); t2.start(); System.out.println("Todas as threads foram iniciadas"); }

DeadLock class DeadLock extends Thread { private Object resourceA; private Object resourceB; public DeadLock(Object a, Object b) { resourceA = a; resourceB = b; }

Cont... public void run() { while (true) { System.out.println("A thread " + Thread.currentThread().getName()‏ + " está esperando pelo lock de " + resourceA); synchronized (resourceA) { System.out.println("A thread " + Thread.currentThread().getName()‏ + " recebeu o lock de " + resourceA); System.out.println("A thread " + Thread.currentThread().getName()‏ + " está esperando pelo lock de " + resourceB); synchronized (resourceB) { System.out.println("A thread " + Thread.currentThread().getName()‏ + " recebeu o lock de " + resourceB); try { Thread.sleep(500); } catch (Exception e) { }

Dead Lock Dois ou mais processos estão esperando por um evento. O problema: os dois processos estão em estado de waiting (aguardando).