Por que não linhas verdes?


33

Embora eu saiba que questões sobre isso já foram abordadas (por exemplo, https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), não sinto que tenha uma resposta satisfatória .

A questão é: por que a JVM não suporta mais linhas verdes?

Diz isso na FAQ Java de estilo de código :

Um encadeamento verde refere-se a um modo de operação para a Java Virtual Machine (JVM) na qual todo o código é executado em um único encadeamento do sistema operacional.

E isso acabou em java.sun.com :

A desvantagem é que o uso de threads verdes significa que os threads do sistema no Linux não são aproveitados e, portanto, a máquina virtual Java não é escalável quando são adicionadas CPUs adicionais.

Parece-me que a JVM poderia ter um conjunto de processos do sistema igual ao número de núcleos e, em seguida, executar threads verdes em cima disso. Isso pode oferecer grandes vantagens quando você tem um número muito grande de encadeamentos que bloqueiam com frequência (principalmente porque a JVM atual limita o número de encadeamentos).

Pensamentos?


5
Para mim, a pergunta parece: Por que fios verdes? Por que reintroduzir o multithreading emulando-o no nível da JVM por vários processos? É muita dor e sobrecarga para aparentemente nenhum ganho além de permitir que os programadores sejam mais generosos com os threads de desova (e não estou convencido de que seja uma vantagem).

4
Bem, trata-se de ter um modelo de programação simultâneo escalável. Atualmente, em Java, se você quiser escalabilidade, alterne para NIO com seu próprio conjunto de encadeamentos. Pelo menos, esse é o meu entendimento.
redjamjar

3
A presença de coisas como < akka.io > que suporta threads leves também me faz pensar que há uma necessidade. Na verdade, encontrei uma discussão bastante boa aqui < stackoverflow.com/questions/7458782/… > #
redjamjar

2
@ delnan Porque a mudança de contexto para custos de threads nativos. Os threads verdes têm muito menos sobrecarga para alternar o contexto e sincronizar interprocessos. Além disso, a quantidade de threads verdes é praticamente ilimitada (pode ser centenas de milhares deles sem muito estresse para o processo da VM), enquanto a quantidade de threads nativos é restrita pelo SO e pela sobrecarga de memória.
Permeakra

Demorou muito tempo para a JVM suportar diretamente os threads nativos. Linhas verdes eram a solução intermediária até então.
Thorbjørn Ravn Andersen 02/03

Respostas:


29

Lembro-me da JVM abandonando segmentos verdes e passando para segmentos nativos. Isso ocorreu por dois motivos simples: os fios verdes eram francamente inúteis e havia a necessidade de oferecer suporte a processadores com vários núcleos com o esforço limitado de desenvolvedor disponível na Sun.

Isso foi uma pena - as linhas verdes fornecem uma abstração muito melhor, permitindo que a simultaneidade seja uma ferramenta útil e não uma pedra de tropeço. Mas fios verdes não são úteis se vários obstáculos não puderem ser superados:

  • eles devem usar todos os núcleos da CPU disponíveis para eles

  • a mudança de contexto deve ser barata

  • I / O podem bloquear qualquer tópico envolvidos nele, mas não qualquer outro segmento e certamente não todos os outros tópicos, o que foi o caso em alguns dos primeiros implementações.

Eu sempre me perguntei por que o multi-threading é tão difícil em Java, mas agora está se tornando mais claro - em última análise, estava relacionado à mudança para threads nativos, que são:

  • bom em usar todos os núcleos da CPU

  • bom em ser verdadeiramente simultâneo, fornecendo E / S independentes, etc.

  • lento na alternância de contexto (comparado com as melhores implementações de thread verde)

  • terrivelmente ganancioso com a memória, limitando assim o número máximo de utilizáveis ​​deles

  • uma abstração ruim para qualquer base para expressar o mundo real, que é altamente concorrente, é claro.

Atualmente, muito tempo do programador agora é usado para codificar E / S sem bloqueio, futuros etc. É uma pena que não tenhamos um nível melhor de abstração.

Para comparação, além do Erlang, o novo idioma Go faz um bom trabalho de enorme simultaneidade. O avô de todos eles continua sendo Occam , ainda um projeto de pesquisa em andamento.


até onde fomos desde o momento em que você postou: O
Dmitry

3
Infelizmente, Rust é outra linguagem que abandonou melhores abstrações de simultaneidade. Eles também decidiram passar de threads cooperativos para threads nativos.
Rick-777

2
@ Rick-777 A ferrugem é muito baixa para fazer isso.
Malcolm

15

Um único processo de falsificação de vários encadeamentos apresenta muitos problemas. Uma delas é que todos os encadeamentos falsos são interrompidos por qualquer falha de página.

A alternativa que você sugere, um conjunto de processos, tem algumas vantagens e algumas desvantagens. A maior vantagem, o isolamento dos 'threads', realmente não o levaria muito aqui. A grande desvantagem, extrema dificuldade de implementação e sincronização menos eficiente, é a causa da morte aqui.

No entanto, concordo que existem alguns aplicativos (não Java) em que um conjunto de processos que você poderia usar como um conjunto de encadeamentos (mas com mais isolamento) seria uma ótima coisa. Threads compartilham praticamente tudo. Com os processos, você pode escolher especificamente o que compartilhar. Que eu saiba, ninguém se esforçou para implementá-lo ainda.


A Occam alega oferecer isso. Era uma linguagem significativa nos anos 80, mas sofria de falta de financiamento para o desenvolvimento e, consequentemente, tornou-se apenas um nicho de pesquisa. Mas suas idéias sobre concorrência são tão sólidas agora como eram na época e ainda precisam ser aprimoradas.
Rick-777

Se você é "multithread" a la golang (programação do tipo "M: N"), teoricamente apenas um thread verde é bloqueado por uma falha de página porque os outros threads podem "pegar a folga" (outros threads verdes). .. softwareengineering.stackexchange.com/questions/222642/…
rogerdpack

13

Não haverá benefício algum para um código Java médio. Java não é Erlang, e programadores Java não têm a mesma mentalidade que os programadores Erlang. O idioma nunca foi projetado para ser usado dessa maneira.

Se você deseja um verdadeiro processo leve - use Erlang e crie milhares de threads se comunicando por meio de mensagens. Em Java, você terá uma dúzia de threads compartilhando uma memória comum com mutexes e semáforos. É apenas um modelo de programação diferente, projetado para um conjunto diferente de problemas.


Portanto, para esclarecer, é uma abordagem útil em Erlang. E, ignorando os problemas da mentalidade Java, isso poderia realmente ajudar?
Redshjar #

1
@redjamjar, é improvável que seja útil em Java, a própria linguagem não é adequada para esse uso, e sua principal (e única) vantagem - o vasto corpo de bibliotecas prontas para uso - não se encaixa bem em um alienígena abordagem de programação.
SK-logic

Sim, se você quiser que o modelo, basta usar Erlang, será uma ordem de magnitude mais fácil
Zachary K

1
! Java = JVM, apenas dizendo :)
Kamil Tomšík

1
@Bane, essas "vantagens" só existem nada se você tem que comparar
SK-lógica
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.