Eu tenho uma dúvida com relação a uma palavra usada em Threads.
No livro do Sommerville, Engenharia de Software, 6º ed., ele fala:
iJava inclui um mecanismo muito simples (thread), que permite criar objetos que são executados simultaneamente.(…)[/i]
Uma thread pode ter alguns estados, dentre eles executando. A JVM enxerga apenas esse estado, mas por trás dele, o Sistema Operacional está alocando quantum para cada uma das threads. As threads, pela perspectiva do sistema Operacional, estão comutando entre os estados em execução e pronto.
Assim, em uma máquina com apenas um processador, apenas uma thread é executada em um determinado tempo.
Assim, não estaria “forçando a barra” ao dizer que as threads permitem criar objetos que são executados simultaneamente, ou Sommerville quis dizer isso na perspectiva da JVM?
Vamos comparar o sistema operacional a um cozinheiro e o seu computador a um fogão. Se seu fogão tiver apenas uma boca, ele é como se fosse um processador com apenas um núcleo. Em um fogão desses, você pode preparar dois pratos, ou um depois do outro, ou então dois ao mesmo tempo. Como é que você faz isso? Você fica tirando e pondo as panelas do fogo (talvez deixando 50% do tempo cada panela, ou então deixando 80% do tempo e 20%, dependendo do preparo do prato). Se o fogo for suficientemente forte, dá para fazer isso (é claro que o cozinheiro pode acabar derrubando alguma panela no chão, mas…)
O fato de ele dizer “simultaneamente” é tanto uma “ilusão” quanto é uma “realidade”. É uma ilusão, no sentido em que apenas uma thread recebe o direito de usar ciclos de CPU em um dado instante, e é uma realidade, no sentido em que cada thread está progredindo junto com as outras, quando estã esperando por I/O ou por outra coisa.
Como você deve saber, muitos programas contém escrita e leitura em disco, ou outros processos de I/O (por exemplo, teclado ou mouse), que não envolvem usar ciclos do processador, e sim dar um comando (o que não gasta muitos ciclos) e esperar algo ocorrer. Por isso, você pode ter vários processos e threads rodando simultaneamente em um único processador - no sentido em que eles estão esperando por algum I/O ser executado.
[quote=entanglement]Vamos comparar o sistema operacional a um cozinheiro e o seu computador a um fogão. Se seu fogão tiver apenas uma boca, ele é como se fosse um processador com apenas um núcleo. Em um fogão desses, você pode preparar dois pratos, ou um depois do outro, ou então dois ao mesmo tempo. Como é que você faz isso? Você fica tirando e pondo as panelas do fogo (talvez deixando 50% do tempo cada panela, ou então deixando 80% do tempo e 20%, dependendo do preparo do prato). Se o fogo for suficientemente forte, dá para fazer isso (é claro que o cozinheiro pode acabar derrubando alguma panela no chão, mas…)
O fato de ele dizer “simultaneamente” é tanto uma “ilusão” quanto é uma “realidade”. É uma ilusão, no sentido em que apenas uma thread recebe o direito de usar ciclos de CPU em um dado instante, e é uma realidade, no sentido em que cada thread está progredindo junto com as outras, quando estã esperando por I/O ou por outra coisa.
Como você deve saber, muitos programas contém escrita e leitura em disco, ou outros processos de I/O (por exemplo, teclado ou mouse), que não envolvem usar ciclos do processador, e sim dar um comando (o que não gasta muitos ciclos) e esperar algo ocorrer. Por isso, você pode ter vários processos e threads rodando simultaneamente em um único processador - no sentido em que eles estão esperando por algum I/O ser executado. [/quote]
Obrigado pela explicação. Eu entendi. Enquanto uma thread espera que um I/O faça o serviço requisitado, uma outra thread trabalha efetivamente. Assim, pode-se ver que ambas estão sendo executadas simultaneamente. Só que esse raciocínio envolve que a máquina tenha DMA. Eu fico mais seguro pensando que a definição não é realista, mas sim ilusória.
hahahhahha … chorei de tanto rir me imaginando como cozinheiro, mas foi muito bom exemplo para entender o conceito de Thread, que o entanglement disponibilizou. Se vc quer entender mais a fundo sugiro que estudo Sistemas Operacionais (S.O), se não me engano vem desde a década de 80 a idéia de processo concorrente, é a simulação de vários processos em único núcleo, por isso que desde do windows 3.1, não existe processo em real time, imagina ficar preso num programa até ele ser finalizado, ou pior, acontecia bastante antigamente encontrava um bug no processo ele simplesmente não finalizava … imagina programar, sem poder ouvir música, navegar na internet. Acho que haveria um suicídios em massa. Bom finalizando, hoje temos processadores com vários núcleos que podemos fazer funções ao qual utilize todo o poder de processamento simultâneo, isso é possível, mas não é o indicado por não ser necessário afinal os sistemas tem o objetivo de ser o mais leve possível, o único programa que vejo realmente utilizar 100% de um processador por necessidade são os sistemas gráficos que utilizam renderização, realocação de milhares de milhões de pontos, utilizando ao máximo o poder de cálculos de pontos flutuantes.
De certo modo ela é ilusória e de certo modo ela não é.
Mesmo que você tenha apenas um processador e uma thread e não tenha mais nada de I/O, apenas memória, a CPU também tem de esperar que a memória seja carregada para o cache e então usá-la - ou seja, de certo modo o processador acaba ficando ocioso de vez em quando.
Não é porque algo está ocioso que “não está trabalhando”.
E é por isso que muitas CPUs têm duas ou mais threads por núcleo, já que você pode organizar suas threads de forma que uma esteja processando algo e outra esteja esperando por um acesso de memória. Dessa forma, você pode aproveitar que uma unidade de processamento aritmético e lógico (ALU) hoje em dia é relativamente pequena, em relação à quantidade monstruosa de memória cache que existe nos processadores modernos, e aproveitar a capacidade de processamento.
De qualquer forma, a frase do Sommerville está correta:
Mesmo se considerarmos que nos casos em que um computador de um núcleo isso não seja possível, o mecanismos de thread ainda permite que se rode processos simultaneos em outros processadores.
Isto é, o mecanismo do Java dá suporte a rodar coisas em paralelo, e de sincroniza-las, desde que seu hardware também dê. O fato do mecanismo “permitir” não significa que numa dada configuração de hardware ele vá conseguir isso (as autobahns alemãs permitem que você diriga um carro a 300km/h, mas isso não significa que elas vão turbinar seu fusquinha, caso você resolva dirigir por lá).
Em todo caso, o time-sharing dá uma ilusão de paralelismo boa o suficiente para que consideremos que duas threads em time-sharing sejam efetivamente simultâneas.
[quote=ViniGodoy]De qualquer forma, a frase do Sommerville está correta:
Mesmo se considerarmos que nos casos em que um computador de um núcleo isso não seja possível, o mecanismos de thread ainda permite que se rode processos simultaneos em outros processadores.
Isto é, o mecanismo do Java dá suporte a rodar coisas em paralelo, e de sincroniza-las, desde que seu hardware também dê. O fato do mecanismo “permitir” não significa que numa dada configuração de hardware ele vá conseguir isso (as autobahns alemãs permitem que você diriga um carro a 300km/h, mas isso não significa que elas vão turbinar seu fusquinha, caso você resolva dirigir por lá).
Em todo caso, o time-sharing dá uma ilusão de paralelismo boa o suficiente para que consideremos que duas threads em time-sharing sejam efetivamente simultâneas.[/quote]
Então, Vini…
(…)que permite criar objetos que são executados paralelamente(…)
O que o autor diz é que a criação de objetos é opcional e, uma vez criados esses objetos Threads, eles executam paralelamente.
Eu também acredito que essa frase está se referindo a uma ilusão de paralelismo, porém, boa o suficiente para acreditar que rodem mesmo paralelamente.
Estou dando uma estudando em threads , li algumas coisas.
E no livro ele fala para considera uma thread como um objeto qualquer em java e classe que implementa Runnable uma tarefa
a ser executada.
Aqui diz que thread é um executor esperando uma tarefa (algo executável ser passado para ele)
e quando isso é feito nós damos o comando thread.start(tarefa).
Isso cria um segmento.
Então por exemplo em uma aplicação
que use uma thread temos dois segmentos
o segmento principal que a pilha de execução do main
e o segmento secundário
que a pilha de execução do run.
O processador com núcleo nesse caso age como cozinheiro mencionado. dando um time slice(fatia de tempo) para cada thread do time sharing(tempo compartilhado).
Nesse livro que lí ao invés de monitor (schedule) é chamado de agendador, mas creio que o termo mais técnico seria escalonador .(imprevisível como tal).
Entendo que ao se falar em thread lidamos com três coisas diferentes o Objeto thread, o segmento em execução criado pela thread e a tarefa a ser executada.
Fiquei com duas dúvidas.
Tanto wait,notify,sleep() servem para comunicação entre threads.
se colocado um wait dentro de uma thread x para uma y
ela(thread) será obrigado a esperar a execução da do segmento da thread y para voltar a sua execução.
Ok acho que funciona assim mesmo e depois disso a mesma irá voltar a sua execução normal.
( thread y tem que avisar as threads que dependem dela através do notifyAll.
Aqui vem a dúvida a thread A dormi e espera ser acordada pela thread y.
Se ela dormi com wait para que serve o comando sleep()?
:oops:
[quote=ViniGodoy]De qualquer forma, a frase do Sommerville está correta:
Mesmo se considerarmos que nos casos em que um computador de um núcleo isso não seja possível, o mecanismos de thread ainda permite que se rode processos simultaneos em outros processadores.
Isto é, o mecanismo do Java dá suporte a rodar coisas em paralelo, e de sincroniza-las, desde que seu hardware também dê. O fato do mecanismo “permitir” não significa que numa dada configuração de hardware ele vá conseguir isso (as autobahns alemãs permitem que você diriga um carro a 300km/h, mas isso não significa que elas vão turbinar seu fusquinha, caso você resolva dirigir por lá).
Em todo caso, o time-sharing dá uma ilusão de paralelismo boa o suficiente para que consideremos que duas threads em time-sharing sejam efetivamente simultâneas.[/quote]
Concordo com você. Com apenas um núcleo a ilusão é bem “realista” diga-se assim. Com mais de um a coisa passa de ilusão para o real.
[quote=Rocklee6544]E no livro ele fala para considerara uma thread como um objeto qualquer em java e classe que implementa Runnable uma tarefa
a ser executada.
[/quote]
Falou besteira. Thread não é um objeto.
Thread é uma linha de execução, é o que você chamou de “segmento”. Aliás, segmento é a tradução literal da palavra thread.
Os objetos da classe Thread fazem duas coisas:
a) Criam uma nova thread (no método start);
b) Informam o estado da thread criada.
Note porém que o objeto da classe Thread não é a thread criada. Ele só a representa.
Da mesma forma, um objeto da classe File não é o arquivo, é só um representante do arquivo.
[quote]Aqui diz que thread é um executor esperando uma tarefa (algo executável ser passado para ele)
e quando isso é feito nós damos o comando thread.start(tarefa).[/quote]
Um objeto da classe Thread é um executor. A thread é o que esse executor gera.
O comando sleep serve para a thread pedir para dormir por conta própria, por alguns milissegundos, sem esperar outra thread acorda-la.
Quando uma thread se põe para dormir, outras podem usar o processador.
Um exemplo clássico do uso de sleep é no loop de um jogo.
Queremos rodar um jogo geralmente a 60 quadros por segundo (é o tempo que o monitor pisca).
Portanto, o tempo de um quadro deve ser 1000 / 60 milissegundos.
Entretanto, pode ser que o computador seja mais rápido que isso, por isso, fazemos o loop de jogos assim:
[code]
long tempoEm60FPS = 1000 / 60; //Tempo que queremos para um quadro
while (oGameEstaRodando) {
long antes = System.currentTimeMillis();
processaLogica();
desenha();
//Calculamos o tempo que levou para processar e desenhar
long tempo = System.currentTimeMillis() - antes;
//Se o computador for mais rápido
if (tempo < tempoEm60FPS) {
//Esperamos o que falta para dar os 60 FPS
Thread.sleep(tempoEm60FPS - tempo);
}
}[/code]
Isso impede que um computador daqui a 5 anos faça o jogo rodar como se você tivesse pressionado o botão de “avançar” do seu aparelho de DVD (um problema que ocorria com jogos antigos).
E também garante que máquinas diferentes rodem o jogo à mesma velocidade, mesmo que seus processadores sejam diferentes (desde que elas consigam a taxa mínima, lógico).
Novamente muito obrigado pelas resposta foram bem esclarecedoras , principalmente a parte do escalonador do SO que é quem seleciona uma thread para execução.
A diferença entre os dois Monitor X escalonador.
E a parte do objeto da classe Thread não ser uma thread , mas sim um representante de uma linha em execução e a funções do objeto dessa classe.(as duas).
O exemplo do sleep foi muito interessante.
Enfim foi muito esclarecedor.
Quando damos um sleep ou wait a thread fica em um estado de suspensão e
podemos dizer que não participa da concorrência com outras thread por um determinado tempo.
Então se tenho 5 thread e uma vai para estado de suspensão o escalonador passa a ter que alternar entre quatro e não mais
cinco threads. Quando a thread volta ao seu estado executável(pronta para execução) ela entra na fila novamente.(nesse momento ela passa a ter direito a uma fatia do time sharing).
Preciso melhorar meu inglês ainda não tenho coragem para me arriscar em um livro de java, alias ter eu até tenho só não tenho confiança na minha interpretação.
Mas irei tentar.
Aqui o que diz é que a thread pode ficar em três estados executável ,em execução e bloqueado.
o terceiro pode ser por vários motivos e nele entendo que a thread passa a não concorrer com as outras por um determinado tempo. (Espero não ter me equivocado em mais nada).
[quote=Rocklee6544]Novamente muito obrigado pelas resposta foram bem esclarecedoras , principalmente a parte do escalonador do SO que é quem seleciona uma thread para execução.
A diferença entre os dois Monitor X escalonador.
E a parte do objeto da classe Thread não ser uma thread , mas sim um representante de uma linha em execução e a funções do objeto dessa classe.(as duas).
O exemplo do sleep foi muito interessante.
Enfim foi muito esclarecedor.
Quando damos um sleep ou wait a thread fica em um estado de suspensão e
podemos dizer que não participa da concorrência com outras thread por um determinado tempo.
Então se tenho 5 thread e uma vai para estado de suspensão o escalonador passa a ter que alternar entre quatro e não mais
cinco threads. Quando a thread volta ao seu estado executável(pronta para execução) ela entra na fila novamente.(nesse momento ela passa a ter direito a uma fatia do time sharing).[/quote]
Isso mesmo.
[quote]Preciso melhorar meu inglês ainda não tenho coragem para me arriscar em um livro de java, alias ter eu até tenho só não tenho confiança na minha interpretação.
Mas irei tentar.
Aqui o que diz é que a thread pode ficar em três estados executável ,em execução e bloqueado.
o terceiro pode ser por vários motivos e nele entendo que a thread passa a não concorrer com as outras por um determinado tempo. (Espero não ter me equivocado em mais nada).[/quote]
Exatamente. A thread fica suspensa geralmente nos seguintes casos:
a) Está esperando ser notificada (pois deu um wait());
b) Pediu para ser suspensa (deu um sleep());
c) Está aguardando uma operação de Entrada/Saída (lendo arquivo, por exemplo) - como mídias físicas (HD, pendrive, disquete, fita) são muito mais lentas que o processador, o SO suspende a thread enquanto dados estão sendo lidos;