Problemas de encadeamento

Ao trabalhar com um kit de ferramentas de widget, é importante compreender o modelo de encadeamento subjacente utilizado para leitura e dispatch de eventos da GUI da plataforma. A implementação do encadeamento da UI afeta as regras que os aplicativos devem seguir ao utilizarem encadeamentos Java em seus códigos.

Dispatch de evento nativo

Debaixo de qualquer aplicativo da GUI, independentemente de sua linguagem ou seu kit de ferramentas da UI, a plataforma do S.O. detecta eventos da GUI e os coloca em filas de eventos de aplicativos. Embora os mecanismos sejam um pouco diferentes em plataformas de sistema operacional diferente, os fundamentos são semelhantes. Conforme o usuário clica com o mouse, digita caracteres ou acerta janelas, o sistema operacional gera eventos da GUI do aplicativo, como cliques do mouse, pressionamentos de teclas ou eventos de pintura da janela. Ele determina qual janela e qual aplicativo devem receber cada evento e coloca-o na fila de eventos do aplicativo.

A estrutura subjacente de qualquer aplicativo da GUI na janela é um loop de eventos. Os aplicativos são inicializados e começam a fazer um loop que simplesmente lê os eventos da GUI na fila e reage de maneira adequada. Qualquer trabalho feito durante a manipulação de um desses eventos deve ocorrer rapidamente para manter o sistema da GUI pronto para responder ao usuário.

As operações longas disparadas por eventos da UI devem ser executadas em um encadeamento separado para permitir que o encadeamento do loop de eventos retorne rapidamente e busque o próximo evento na fila do aplicativo. No entanto, o acesso aos widgets e à API da plataforma a partir de outros encadeamentos deve ser controlada com bloqueio e serialização explícitos. Um aplicativo que falha em seguir as regras pode provocar a falha de uma chamada do sistema operacional ou, o que é pior, bloquear o sistema da GUI inteiro.

Encadeamentos da UI do kit de ferramentas

Os programadores da GUI nativa utilizando C estão bem familiarizados com as considerações de design para trabalhar com o loop de eventos da plataforma. No entanto, os kits de ferramentas de widget de nível superior em Java muitas vezes tentam defender os desenvolvedores de aplicativo dos problemas de encadeamento da UI, ocultando o loop de eventos da plataforma.

Uma maneira comum de conseguir isso é configurar um encadeamento dedicado da UI do kit de ferramentas para leitura e dispatch do loop de eventos e para lançamento dos eventos em uma fila interna atendida por aplicativos que estão sendo executados em encadeamentos separados. Isso permite ao kit de ferramentas responder ao sistema operacional em tempo suficiente, embora sem o posicionamento de qualquer restrição na sincronização do aplicativo na manipulação do evento. Os aplicativos devem continuar utilizando técnicas de bloqueio especiais para acessar o código da UI a partir do encadeamento do aplicativo deles, mas isso é feito consistentemente em todo o código, pois todo o código de aplicativo está sendo executado em um encadeamento que não é da UI.

Embora isso soe como uma tentativa de "proteger" os aplicativos dos problemas de encadeamento da UI, na prática isso causa muitos problemas.

Fica difícil depurar e diagnosticar problemas quando a sincronização dos eventos da GUI depende da implementação do encadeamento de Java e do desempenho do aplicativo.

As plataformas de GUI modernas executam muitas otimizações com a fila de eventos. Uma otimização comum é reduzir eventos de pintura consecutivos na fila. Cada vez que parte de uma janela deve ser repintada, a fila pode ser verificada pela existência de sobreposição ou de eventos de pintura redundantes dos quais ainda não foi feito o dispatch. Esses eventos podem ser unidos em um evento de pintura, causando menos oscilação e a execução menos freqüente do código de pintura do aplicativo. Essa otimização será perdida se o kit de ferramentas de widget estiver tirando os eventos da fila rapidamente e lançando-os em uma fila interna.

Alterar a percepção do desenvolvedor com relação ao modelo de encadeamento causa confusão nos programadores que possuem experiência em programação de sistema de GUI nativa em outras linguagens e em outros kits de ferramentas.

Encadeamento da UI do SWT

O SWT segue o gabarito de encadeamento diretamente compatível com as plataformas. O programa aplicativo executa o loop de eventos no seu segmento principal e faz o dispatch dos eventos diretamente desse encadeamento. Esse é o "encadeamento da UI" do aplicativo.

Nota:  tecnicamente, o encadeamento da UI é aquele que cria o Vídeo.Na prática, é também aquele que executa o loop de eventos e cria os widgets.

Como todo o código de evento é disparado do código de evento da UI do aplicativo, o código do aplicativo que manipula os eventos pode acessar livremente os widgets e fazer chamadas de gráfico sem qualquer técnica especial. No entanto, o aplicativo é o responsável por bifurcar os encadeamentos computacionais durante a execução de operações longas, em resposta a um evento.

Nota:  o SWT irá disparar uma SWTException para qualquer chamada feita de um encadeamento que não seja da UI e que deva ser feita de um encadeamento da UI.

O encadeamento principal de um aplicativo do SWT, incluindo o loop de eventos, é semelhante ao seguinte:

   public static void main (String [] args) {
      Display display = new Display ();
      Shell shell = new Shell (display);
      shell.open ();
      // iniciar o loop de eventos. Paramos quando o usuário faz
      // algo para descartar nossa janela.
      while (!shell.isDisposed ()) {
         if (!display.readAndDispatch())
            display.sleep();
      }
      display.dispose ();
   }

Assim que os widgets são criados e o shell é aberto, o aplicativo lê e faz o dispatch dos eventos na fila do sistema operacional até a janela do shell ser descartada. Se não há eventos disponíveis para nós na fila, dizemos ao vídeo para dormir, a fim de dar aos outros aplicativos a chance de serem executados.

Nota:  o gabarito de encadeamento mais comum para um aplicativo do SWT é executar um único encadeamento da UI e realizar operações longas em encadeamentos computacionais. No entanto, o SWT não restringe os desenvolvedores a esse gabarito. Um aplicativo poderia executar vários encadeamentos da UI, com um loop de eventos separado em cada encadeamento.

O SWT fornece métodos de acesso especiais para chamada de código de widget e de gráfico de um encadeamento em segundo plano.

Executando Código de um Encadeamento que Não é da UI

Os aplicativos que desejam chamar o código da UI de um encadeamento que não é da UI devem fornecer um Executável que chame o código da UI.Os métodos syncExec(Runnable) e asyncExec(Runnable) na classe Display são utilizados para executar esses executáveis no encadeamento da UI no momento apropriado.

O fragmento de código a seguir demonstra o padrão para utilização desses métodos:

   // faça computações que consumam bastante tempo
   ...
   // agora atualize a UI. Não dependemos do resultado,
   // portanto, utilize assincronamente.
   Display.getDefault ().asyncExec (new Runnable () {
      public void run () {
         myWindow.redraw ();
      }
   });
   // agora faça mais computações
   ...

O workbench e os encadeamentos

As regras de encadeamento são bastante claras quando se está implementando um aplicativo SWT desde o início, pois você controla a criação do loop de eventos e a decisão de bifurcar os encadeamentos computacionais no aplicativo.

Se você estiver contribuindo o código do plug-in para o workbench, não há "mágica" de encadeamento oculta no código do JFace ou do workbench. As regras são diretas:

Copyright IBM Corporation e outros 2000, 2003.