Pergunta

Ao usar JavaFX 8, precisamos executar interações com a GUI via Platform.runLater, caso contrário, eles lançarão exceções se executados em outro thread.

Contudo a implementação de Platform.runLater nunca verifica se está atualmente no thread JavaFX.

Eu escrevi o seguinte método:

public static void runSafe(final Runnable runnable) {
    Objects.requireNonNull(runnable, "runnable");
    if (Platform.isFxApplicationThread()) {
        runnable.run();
    }
    else {
        Platform.runLater(runnable);
    }
}

Isso garante que ele nunca possa ser executado em um thread que não seja de aplicativo FX.

Existe alguma razão para que a implementação padrão não cause esse tipo de curto-circuito?

Foi útil?

Solução

runLater essencialmente coloca seu Runnable em uma fila para execução quando o thread FX estiver disponível.O método pode ser acessado por meio de threads não-FX.Imagine que alguns outros threads colocaram tarefas no runLater fila e depois ligando runLater novamente, seja do thread FX ou não, deve colocar a nova tarefa no final dessa fila.

Com o curto-circuito que você propõe, as tarefas anteriores teriam basicamente uma prioridade mais baixa, o que pode não ser desejável.

Outras dicas

Ao chamar uma função, e a função é chamada de 'runLater', espero que ela seja executada mais tarde, não agora.

Parece-me que a implementação está fazendo a coisa certa, com base no nome, e é documentação:

Execute o Runnable especificado no thread do aplicativo JavaFX em algum momento não especificado no futuro.

Este método, que pode ser chamado de qualquer thread, postará o Runnable em uma fila de eventos e retornará imediatamente ao chamador.Os Runnables são executados na ordem em que são postados.Um executável passado para o método runLater será executado antes de qualquer Runnable passado para uma chamada subsequente para runLater

Se você não quiser que o código seja executado mais tarde, não peça que ele seja executado mais tarde.Isso é o que você essencialmente fez com seu código.

Eu vi pessoas ligando EventQueue.invokeLater do EDT em Swing ocasionalmente...é, segundo o cânone, uma técnica legítima.Portanto, esta é a mesma situação no JavaFX, a menos que eu esteja muito enganado.

Pessoalmente, tenho minhas dúvidas sobre essa técnica, no entanto.Ver essa questão:a resposta escolhida usa invokeLater porque selectAll() precisa que todos os eventos EDT atuais sejam concluídos antes de serem chamados:esta solução garante efectivamente que selectAll não pode ser executado antes do outro código EDT acontecer aqui.

Mas esta resposta, afirmo, tem vulnerabilidades.Veja a resposta que sugeri (escrita em Jython, mas deve ser compreensível).Suponha que alguém defina “contagem de cliques para iniciar a edição” como 1.Suponhamos, o que é mais preocupante, que algo imprevisível aconteça entre o invokeLater e a selectAll.A menos que você tenha certeza absoluta de que não possui nenhum mecanismo alternativo, ou tenha certeza absoluta de que os eventos e objetos dos dois threads estão completamente "desacoplados", eu pessoalmente diria para evitar chamar runLater do encadeamento JavaFX.

A simultaneidade está sempre esperando para morder você.Portanto, é melhor usar essas técnicas com extremo cuidado!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top