quinta-feira, 12 de novembro de 2009

Algoritmos de trocas de páginas

Por Taiany Géssica e David Rocha

Algoritmos de trocas de páginas

Os algoritmos de trocas de páginas são políticas definidas para escolher quais páginas da memória dará lugar à página que foi solicitada e que precisa ser carregada. Isso é necessário quando não há espaço disponível para armazenar a nova página.

O sistema operacional deverá escolher, entre as páginas que estão na memória principal, uma para remover e permitir que a nova página seja trazida para a memória. Se esta página a ser removida foi modificada enquanto estava na memória, ela deverá ser salva no disco antes de poder trazer a nova página. Caso uma página que é freqüentemente acessada seja removida da memória, muito provavelmente ela deverá ser trazida de volta a memória em um curto período, causando um gasto de tempo evitável.

Para gerenciar a memória, e evitar que páginas freqüentemente acessadas sejam removidas da memória, são utilizados os algoritmos de troca de página.

Esses algoritmos que tratam dos problemas de trocas de páginas são aqueles que implementam as estratégias de substituição (replacement strategies) e são denominados algoritmos de troca ou algoritmos de substituição de páginas.

Neles podemos destacar os algoritmos Random, First In First Out, Second Chance, Clock, Clock 2, Last Recently Used (LRU), Last Frequently Used (LFU), Not Recently Used (NRU).

O Algoritmo de troca de páginas Random Page Replacement é um algoritmo de baixa sobrecarga que seleciona aleatoriamente a página que deverá ser substituída.

Suas chances de sucesso são maiores quando há um maior número de páginas existentes. É um algoritmo rápido e de implementação simples, mas é raramente utilizado, pois a página a ser substituída pode ser a próxima a ser necessária.

O First In First Out (FIFO) é um algoritmo que tem como idéia central que as páginas que estão há mais tempo na memória podem ser substituídas, ou seja, as primeiras que entram são as primeiras que saem. Para isto associa se um timepstamp (Marca de tempo), que cria uma lista de páginas por idade, ou seja, por entrada. Cada nova página trazida à memória é colocada no final de uma lista ligada. Ao ocorrer uma falta de página, a página que estiver no começo desta lista será removida. Embora esse algoritmo seja provável e lógico não necessariamente é correto, pois páginas há mais tempo na memória podem ser usadas com muita freqüência. Assim ele não é utilizado da forma pura, mas sim com suas variações.

O Second Chance (Segunda Chance) é uma variação da estratégia FIFO. Como a deficiência do FIFO é que uma página de longa duração e de uso intenso pode ser indevidamente substituída. O algoritmo de troca de páginas segunda chance escolhe a página mais antiga, porém antes de fazer a substituição verifica o bit de referência da mesma. Se o bit estiver em 1, significa que a página foi usada, assim o algoritmo troca sua marca de tempo (timepstamp) e ajusta o bit de referência para zero, simulando uma nova página na memória. Ele fornece uma “segunda chance” para as às páginas antigas de permanecerem na memória primaria.

Basicamente, esse algoritmo trabalha fazendo com que as páginas fiquem em uma lista onde no início se encontram as páginas mais velhas que se após a verificação constatar que a página foi usada será reposicionada para o final (mais novas).





O algoritmo de troca de páginas Clock (relógio) é outra variação da estratégia FIFO. Enquanto o algoritmo de troca de páginas FIFO substitui uma página em função de sua idade na memória e o algoritmo second chance verifica o bit mantendo na memória páginas de uso intenso através da renovação de seu timestamp. O clock mantém uma lista circular, onde se o bit de referência é 1 o seu valor é trocado por zero, e a referência da lista é movida conforme os ponteiros de um relógio, caso contrario a página será substituída.



O clock 2 é igual ao Clock, só que existem 2 ponteiros, enquanto um vai apagando os bits R, o outro verifica se a página pode ser removida.


O algoritmo de troca de paginas LRU (least Recently Used ou menos usada recentemente) tem como funcionalidade identificar a página menos utiliza por mais período de tempo.

É necessário que cada página possua o timestamp. Ele tem como idéia que as páginas usadas recentemente logo não serão usadas e retira da memória a página que há mais tempo não é utilizada.

A implementação ocorre através de listas, sendo que a página mais recentemente usada se localiza no início da lista e a menos usada no final. É necessário atualizar a lista a cada referência à memória.

Sua deficiência ocorre em laços longos ou chamados com muitos níveis de profundidade, pois a próxima pagina a ser usada pode ser uma das menos usadas recentemente.

O Least Frequently Used – LFU (Menos usada frequentemente) ou Not Frequently Used – NFU (Não usada frequentemente) são algoritmos de estratégia para o LRU, que calcula a freqüência de uso das páginas de forma a identificar qual página foi menos intensivamente utilizada. Sua deficiência é que ainda é possível páginas pesadas que foram utilizadas durante uma certa etapa do processamento permaneçam sem necessidade na memória primária em relação a outras etapas mais curtas, cujas páginas não terão uso tão intenso, levando a substituições inúteis.

O algoritmo NRU (Not Recently Used) tem como idéia escolher a página que está há mais tempo sem uso para efetuar a troca, sendo que a página mais recente é excluída da decisão e através do método FIFO, é feita a escolha dentre as outras de qual página deve sair. Este algoritmo é utilizado em vários sistemas devido sua forma simples, de fácil implementação e desempenho adequado.

Exemplos de S.O

No Linux, a memória funciona com prioridade para processos que estão em execução. Quando um processo termina, havendo espaço na memória, o sistema mantém resíduos desse processo na memória para que uma possível volta a processo seja mais rápida. Caso essa memória RAM esteja lotada com processos que estão em execução, aí se faz uso da memória SWAP (troca).

O sistema operacional MS Windows 95 utiliza a estratégia de substituição de páginas LRU (least recently used ou menos usada recentemente).

quinta-feira, 5 de novembro de 2009

Paginação de memória.

Este trabalho consiste na explicação do tema: Paginação de memória.
Diogo Libana / Francisco Henrique

1.1 Conceitos de paginação

A técnica de paginação surgiu com a necessidade de evitar o desperdício de memória causada pelas partições variáveis em função da fragmentação externa. A fragmentação externa consiste no fato de cada programa necessitar ocupar uma área continua na memória, se essa necessidade for eliminada e partes do programa puderem ser espalhadas pela memória, o problema da fragmentação externa estaria acabado e é ai que entra a paginação. A paginação nada mais é que o programa poder ser espalhado por áreas não continuas da memória.
A paginação ocorre quando o programa é executado, o mesmo é escrito com a suposição de que ele vai ocupar uma área continua na memória, ou seja, que ocupará a memória lógica. O endereço da memória lógica é dividido em duas partes o numero da página lógica e o deslocamento dentro da memória lógica.
Exemplo de memória física/lógica
Num. Des. Mem
000 | 00 | A1
000 | 01 | A2
000 | 10 | A3
000 | 11 | A4
O a primeira coluna (Num.), é o numero da pagina lógica, a segunda coluna (Des.) é o deslocamento dentro da tabela, ao ser criada a pagina lógica é também criada a página física com o mesmo formato da página lógica só diferem que a memória física não necessita que suas páginas estejam na mesma ordem que as páginas na memória lógica, mas precisa que o deslocamento dentro das páginas seja o mesmo tanto na memória física quanto na lógica, por tanto a página da memória física será carrega com o mesmo formato da memória lógica, tendo diferente apenas seus endereço de página, durante essa carga é criada a tabela de páginas. Essa tabela é usada para saber qual página da memória lógica corresponde à página da memória física.

1.2 Tabela de páginas

Cada entrada na tabela de páginas possui o endereço da pagina lógica para a página física, assim se obtendo o endereço da página física correta, já o endereço de deslocamento da página é o mesmo tanto para a página física quanto para a página lógica. Agora juntamos os dois números primeiro o endereço da página depois o deslocamento e temos o endereço físico do byte em questão na tabela física a figura abaixo mostra com mais clareza como é feito esse processo na tabela de páginas.

Vamos pegar o exemplo de Y2, na página lógica Y2 tem o seguinte endereço página 001 e deslocamento 01, pegando o numero da página lógica e comprando na tabela de páginas sabemos que o numero da página física de Y2 é 101 e como o deslocamento é igual em ambas as paginas 01, descobrimos o endereço do byte Y2 na página física 101 01.
O tamanho de uma página pode variar entre 1Kbytes a 8Kbytes, os espaços de endereçamento lógico variam nos Gbytes para máquinas atuais, a memória física vem da capacidade de endereçamento do processador e não a quantidade de memória que é instalada na máquina.
No processo de paginação a unidade de alocação sempre ocupa um numero inteiro de páginas físicas, assim gerando uma fragmentação interna. Imagine o exemplo, um programa precisa de 26Kbytes para ser executado e o tamanho de cada página é 4Kbytes iriam ser ocupadas pelo programa sete páginas totalizando 28Kbytes e gerando assim uma fragmentação interna de 2Kbytes e geral é esperada uma fragmentação interna de página/2 para cada processo.

1.3 Tamanho das paginas
Aqui abordaremos as vantagens e as desvantagens em utilizarmos grandes paginas durante o processo de paginação.
Quanto maior a página menores serão os gastos com a tabela de páginas e aumentará a eficiência da (E/S) do disco, ao mesmo tempo paginas maiores resultam em uma maior fragmentação interna. O tamanho das paginas não é definido pela arquitetura do SO, quem é responsável por isso é o hardware que gerencia a memória.
O gerenciador de memória tem que manter um controle sobre as paginas que estão preenchidas e as que não estão preenchidas, uma forma de realizar esse controle é com o um mapa de bits onde indica um para página usada e zero para página livre, bastaria o gerenciador percorrer suas páginas e encontrar a primeira livre (zero) mas imagine uma memória física de 1Gbytes com quase toda sua extensão já preenchida esse processo iria demorar um pouco. A alternativa para contornar esse problema é manter uma lista encadeada com os números das páginas livres. Com essa lista bastaria pegar o primeiro numero da lista e o sistema gerenciador de memória não precisaria ficar percorrendo toda a extensão da memória toda vez que precisasse de uma pagina livre.

1.4 Níveis de paginação

Uma possibilidade para implementação da paginação de memória seria a tabela de página ser criada de forma contínua, porém deste modo haveria fragmentação de memória no que se refere as tabelas, para solucionar este problema dividiu-se a tabela de página em níveis, o mais comum é o gerenciamento de dois níveis de tabelas, um contendo um diretório de tabelas e outro contendo as tabelas de segundo nível, deste modo as tabelas são criadas de acordo com a demanda e indexadas neste diretório, como mostramos na figura abaixo:



1.5 Exemplo de paginação no linux

No Linux, um endereço virtual é dividido em 5 campos: diretório de páginas (PGD), diretório superior de páginas (PUD), diretório intermediário de páginas (PMD), tabela de páginas (PTE) e deslocamento (offset). A arquitetura x86 possui um espaço de endereçamento de 32 bits; quando são utilizadas páginas de 4 KiB (o padrão) o PUD e o PMD não são utilizados; o PGD e o PTE usam 10 bits cada, e o deslocamento usa 12 bits.

Memória virtual + Segmentação

Aluno: Andre Ferreira Fiche

MEMÓRIA VIRTUAL

É a técnica de gerenciamento que combina a memória principal e a secundária dando ao usuário uma idéia de que existe mais memória principal.
*Desvincula o endereçamento feito pelo programa dos endereços físicos da memória principal;
*Um programa residente na memória virtual faz referências a endereços virtuais;
*O endereço virtual é traduzido para o endereço físico através de mapeamento;
*Os programas podem ser muito maiores que a sua memória física, apenas uma parte do programa está residente na memória em um determinado instante, o restante do programa fica na memória secundária até ser referenciado.

SEGMENTAÇÃO

• A memória virtual discutida até agora é unidimensional, dado que vai de 0 até um endereço máximo.
Em alguns casos isto representa um problema
Tomemos como exemplo a execução de um compilador, que durante a sua execução gera.

1. O texto fonte pre-processado.
2. Uma tabela de símbolos
3. Uma tabela de constantes
4. Uma árvore sintática
5. Uma pilha.

• Os quatro 1º itens crescem continuamente durante a compilação, enquanto a pilha varia de tamanho.
Em uma memória unidimensional estas informações teriam que serem colocadas de
forma contínua no espaço de endereçamento virtual
Imagine o que acontece quando um programa tem um número extremamente grande de variáveis e todo o resto normal.

Nota-se a necessidade de um mecanismo capaz de livrar o programador da contração e expansão de tabelas, da mesma maneira que a memória virtual elimina a preocupação de organizar o programa em overlays
Uma solução extremamente direta é prover a máquina com vários espaços de endereçamento independentes, chamados segmentos
Cada segmento tem um tamanho dinâmico e independente dos outros (de 0 a um máximo)

Para especificar um endereço nesta memória segmentada e bidimensional, o programa deve fornecer um endereço composto de 2 partes: um no. de segmento e um endereço dentro do segmento
Permite que cada tabela cresça ou encolha, Independentemente.
É preciso enfatizar que cada segmento é uma entidade lógica conhecida e utilizada pelo programador, normalmente para armazenar informações relacionadas.
Segmentos podem ter diferentes proteções

– EX: um segmento que armazena código pode ser marcado como somente execução
– Um segmento que armazena constantes, como somente leitura.
– Segmento que possui a pilha como leitura/escrita

• Tentativas de acesso indevidas podem ser capturados e tratados pelo hardware ou SO.
A proteção faz bem mais sentido em uma memória segmentada que em uma paginada, dado que o conteúdo de cada página (ao contrário do conteúdo de cada segmento) é acidental
Embora seja possível se colocar alguns bits de proteção em cada entrada na tabela de pág. a fim de especificar o acesso permitido, o programador deveria manter o controle de onde estão os limites das pág. em seu espaço de endereçamento, para poder utilizar esta propriedade.
A paginação foi criada exatamente para livrar o programador deste tipo de tarefa.

A segmentação difere da paginação em um ponto essencial: as pág. tem tamanho fixo e os segmentos não.
A figura a seguir mostra um exemplo de memória física com cinco segmentos, onde ocorrem as seguintes operações.

1. O seg. 1 é removido e o 7 colocado em seu lugar
2. O seg. 4 é removido e o 5 colocado em seu lugar
3. O seg. 3 é removido e o 6 colocado em seu lugar
(a)-(d) Desenvolvimento de fragmentação externa
(e) Remoção da fragmentação via compactação

• Após algum tempo de execução a memória estará dividida em regiões com segmentos ou lacunas.
Este fenômeno, chamado de fragmentação externa desperdiça memória nas lacunas
Isto pode ser sanado com a compactação dos segmentos.

HIBRIDO

Se os segmentos são grandes talvez seja desnecessário, ou mesmo impossível mantêlos totalmente na memória
Isto gerou a idéia de paginação dos segmentos, de modo que apenas as pág. de cada segmento realmente necessárias terão que estar na memória
Esta paginação funciona exatamente da mesma maneira que de modo isolado, só que divide o espaço de endereçamento de cada seg. em pág., ao invés do espaço de endereçamento como um todo
Várias arquiteturas e SO suportam e utilizam sementos paginados (ex: intel x86 e os SO Linux e Windows)

quinta-feira, 29 de outubro de 2009

O Escalonamento de Processos no Mac OS

Por Vítor Rideik e Thiago Carrere


O escalonamento de processadores é a forma com os processadores existentes
Num sistema computacional são utilizados para efetuar o processamento,
Isto é, é como os processos são distribuıdos para execução nos Processadores.

Tanenbaum propõe a seguinte definição:

Quando mais de um processo é executável, o sistema operacional
Deve decidir qual será executado primeiro. A parte do sistema operacional dedicada a esta decisão é chamada escalonador (scheduler) e o algoritmo utilizado é chamado algoritmo de escalonamento
(scheduling algorithm). [TAN92, p. 62]

O escalonador de processos do Mac OS X é derivado do escalonador OSFMK, porém várias modificações foram feitas para o tratamento de interatividade no projeto de escalonador base.
Assim como o kernel do FreeBSD (5.0BSD), o escalonador de processos do Mac OS X escalona os processos baseado numa variante do algoritmo de múltiplas filas com realimentação, porém divide as filas de prioridades em 4 grupos de processos, agrupados de acordo com suas características.

  1. Normal: Prioridade das aplicações normais do usuário.
  2. Sistema: Prioridade das aplicações do sistema, com prioridade superior as threads normais de usuário.
  3. Kernel: Classe reservada para threads em espaço de kernel que necessitam rodar
    Com uma prioridade superior às threads de sistema.
  4. Tempo real Threads nas quais a prioridade está baseada na necessidade de reservar
    uma fração pré-definida de ciclos de clock, independente de outras
    atividades sendo executadas no sistema.

No caso de tarefas de tempo real, È feito um controle forte pela aplicação no número de ciclos do processador a serem utilizados. Assim, o programador utiliza chamadas de sistema para requisitar ao sistema rodar por A ciclos nos próximos B ciclos. Por exemplo, um processo de tempo real pode requisitar ao kernel que, para que ele possa executar corretamente dentro dos seus padrões mínimos aceitáveis, ele necessite, a cada 7000 ciclos, 3000 ciclos reservados a ele.

Caso a aplicação não respeite o número de ciclos requisitados, ou seja, não faça uma operação de E/S ou use a chamada de sistema sched yield, um processo de tempo real será penalizado dentro de sua fila de prioridades, sendo inclusive possível a migração para o grupo de processos Normal, visando um maior desempenho e justiça no sistema.

A escolha do processo a ser executado obedece o algoritmo de Múltiplas Filas com realimentação, sendo executados os grupos de filas de maior prioridade (Tempo real) e por último o grupo de filas de prioridade de usuário (Normal).
A migração entre os diferentes grupos de threads e feita através do nível de prioridade explicitada pelo usuário. A migração entre as filas de prioridade dentro do grupo de tarefas de usuário é determinada pelo determinador de interatividade.

Como o Sistema Operacional gerencia a memória

Ricardo Verzi e Michele Martins

Alocação Contígua Simples: A forma mais simples de gerenciar a memória é dividindo ela em duas partes, mais conhecida como Alocação Contígua Simples, uma parte para o S.O e a outra para o uso dos processos do usuário. A parte dedicada aos processos do usuário é subdivida em partições de tamanhos iguais ou diferentes porem sempre fixas, a alocação contígua simples era utilizada em antigos S.O.
Multiprogramação com Partições Fixas: A principal virtude desse modelo de gerenciamento de memória reside no fato de que a CPU pode ser utilizada de uma maneira mais proveitosa. Em sistemas de compartilhamento de tempo, ter múltiplos processos na memória simultaneamente significa que quando um processo é bloqueado esperando a E/S acabar, outro pode utilizar a CPU.

O S.O. é responsável pelo controle das partições mantendo informações como partições alocadas, partições livres e tamanho das partições. Quando o sistema operacional gerencia a memória do computador, duas grandes tarefas precisam ser cumpridas.
1. Cada processo deve ter memória suficiente para ser executado. Ele não pode utilizar a memória de outro processo e outro processo também não pode utilizar a sua memória.
2. Os diferentes tipos de memória no sistema devem ser bem utilizados para que cada processo seja executado de forma eficaz.

Paginação: Quando o computador tem pouca memória RAM e precisa de mais imediatamente, o Windows usa o espaço em disco rígido para simular memória RAM do sistema. Isso é conhecido como memória virtual e é freqüentemente denominado arquivo de paginação. O tamanho padrão do arquivo de paginação da memória virtual (denominado pagefile.sys) criado durante a instalação tem 1,5 vezes a quantidade de RAM do computador.
É possível otimizar o uso da memória virtual dividindo o espaço entre as várias unidades e removendo-a de unidades mais lentas ou muito acessadas. Para melhor otimizar o espaço da memória virtual, divida-o entre o maior número possível de discos rígidos físicos. Ao selecionar unidades, tenha as seguintes diretrizes em mente:
- Evite ter um arquivo de paginação na mesma unidade que os arquivos de sistema.
- Não coloque vários arquivos de paginação em partições diferentes no mesmo disco rígido físico.

Limite mínimo recomendado e máximo de memória física

WINDOWS XP

Windows XP Professional – 32 bit
Mínimo recomendado 128 MB
Máximo recomendado 4 GB

Windows XP Professional – 64 bit
Mínimo recomendado 256 MB
Máximo recomendado 16 GB

WINDOWS VISTA

- Windows Vista Ultimate
Mínimo 512 MB
Recomendado 1 GB
Máximo 125 GB

- Windows Vista Home Premium
Mínimo 521 MB
Recomendado 1 GB
Máximo 16 GB

Escalonamento no Windows XP

Por Jones Henrique e Luiz Valério

Escalonamento de Processos

O escalonamento de processos ou agendador de tarefa é uma atividade organizacional feita pelo escalonador (scheduler) da CPU ou de um sistema distribuído, possibilitando executar os processos mais viáveis e concorrentes, priorizando determinados tipos de processos, como os de I/O Bound e os computacionalmente intensivos.

O escalonador de processos de 2 níveis escolhe o processo que tem mais prioridade e menos tempo e coloca-o na memória principal, ficando os outros alocados em disco; com essa execução o processador evita ficar ocioso.

Escalonamento no Windows XP

O Windows XP é um sistema operacional gráfico de 32bits, multitarefa preenptiva e plug and play que aproveita melhor os recursos das máquinas de 386 para cima.

Multitarefa é a capacidade que o Windows tem de executar vários processos (aplicativos) ao mesmo tempo. Existem dois modos de Multitarefa: a multitarefa preemptiva que é utilizada por aplicativos de 32 bits baseados em Windows 95 e a multitarefa cooperativa que é utilizada por aplicativos de 16 bits baseados em Windows 3.1.

Em um sistema Multitarefa preemptivo, cada encadeamento é executado durante um tempo determinado ou até que outro encadeamento de prioridade maior esteja pronto para ser executado. Como o agendamento é controlado pelo sistema operacional sem a cooperação do aplicativo, torna-se mais difícil para um programa ou encadeamento monopolizar o processador. Para impedir que encadeamentos de processos diferentes tenham acesso a um recursos que não podem ser compartilhados (como uma porta serial), o programa pode definir semáforos (sinalizadores especiais utilizados pelo programa) para bloquear este recurso até que ele termine de ser utilizado. No Windows XP, programas do MS-DOS e de 32 bits baseados no Windows são Multitarefa Preemptiva.

Em sistema Multitarefa cooperativos (também denominados não-apropriativos), um encadeamento é executado até que voluntariamente abandone o processador. O programa determina quando o encadeamento pára a execução. No Windows XP, programas de 16 bits baseados no Windows são Multitarefa de modo cooperativo, entre si. Todos os programas de 16bits baseados no Windows, juntos, são tratados como uma única tarefa para o Multitarefa Preemptivo. Este processo Multitarefa híbrido é necessário para manter a compatibilidade com programas de 16 bits baseados no Windows que controlam sua própria execução.

quinta-feira, 24 de setembro de 2009

Threads com Java

por Peter Jandl Jr

Threads
Uma thread define um fluxo de execução independente dentro de um programa e permite
que sejam isoladas tarefas específicas dentro deste. Como as threads são partes do mesmo programa, i.e., fazem parte de um mesmo contexto computacional, então os recursos do
sistema reservados para um programa estão disponíveis para todas as suas threads, e por isso
as threads são consideradas processos leves. Em sistemas onde as threads são suportadas,
programas com um único fluxo de execução (programas sequenciais comuns) são denominados
single-threaded ou de thread única. Já aqueles que definem múltiplos fluxos de execução são
chamados de multithreaded.

O uso das threads pode tornar um programa eficiente e versátil, garantindo que sua interface
se mantenha responsiva, mesmo enquanto o programa executa suas tarefas, ou permitindo
que várias tarefas sejam realizadas ao mesmo tempo.

O uso de threads na plataforma Java é relativamente simplificado, sendo que sua API Java inclui classes especialmente destinadas ao uso e controle das threads que são: Thread e ThreadGroup, além da interface Runnable.

A Classe Thread
A classe Thread, pertencente ao pacote java.lang, permite representar um fluxo independente
de execução dentro de um programa. Basicamente define-se uma nova thread através da
criação de uma subclasse de Thread, na qual se implementa o método run(), que contém o
código que a ser executado. Por exemplo:

class MinhaThread extends Thread {
public void run() {
System.out.println("Inicio: " + getName());
for (int i=0; i<5;>
System.out.println(i + "-" + getName());
}
System.out.println("Fim: " + getName());
}

}
Uma thread assim definida imprimirá no console a contagem de 0 até 5, acompanhada de
seu próprio nome. No início e fim do método run() ocorre a impressão de uma mensagem
indicativa. Para criar uma thread declara-se um objeto de classe e usa-se o operador new
para instanciar o novo objeto (tal como para qualquer outro objeto Java) definindo ou não
um nome para a nova thread:

MinhaThread minhaThread1 = new MinhaThread();
MinhaThread minhaThread2 = new MinhaThread("A Minha Thread");


A instanciação de uma thread não basta para colocá-la em execução. É necessário iniciá-la
explicitamente através do método start(), que providencia o escalonamento da thread pelo
sistema operacional e a consequente execução do método run(), como segue:

minhaThread1.start();

Segue um outro exemplo:

public class TestaThreads {
public static void main(String a[]) {
System.out.println("Inicio: main");
MinhaThread mt1 = new MinhaThread(),
mt2 = new MinhaThread(), mt3 = new MinhaThread();
mt1.start(); mt2.start(); mt3.start();
System.out.println("Fim: main");
}
}
class MinhaThread extends Thread {
public void run() {
System.out.println("Inicio: "+ getName());
for (int i=0; i<5;> System.out.println(i + -"+ getName());
System.out.println("Fim: "+ getName());
}
}


Se executado, este exemplo produz o seguinte resultado:
Referências

  • JANDL JR. Peter. Java 6 - Guia de Consulta Rápida. São Paulo: Novatec, 2008.
  • JANDL JR. Peter. Java - Guia do Programador. São Paulo: Novatec, 2007.
  • Sun. Classe Thread. Disponível em:
    http://72.5.124.55/javase/6/docs/api/java/lang/Thread.html
  • Sun. Interface Runnable. Disponível em:
    http://72.5.124.55/javase/6/docs/api/java/lang/Runnable.html