Que lições você aprendeu de um projeto que quase / realmente falhou devido a um multithreading ruim?
Às vezes, a estrutura impõe um certo modelo de encadeamento que torna as coisas em uma ordem de magnitude mais difíceis de acertar.
Quanto a mim, ainda estou para me recuperar da última falha e sinto que é melhor não trabalhar em nada que tenha a ver com multithreading nesse quadro.
Eu descobri que era bom em problemas de multithreading que possuem simples junção / forquilha e onde os dados trafegam apenas em uma direção (enquanto os sinais podem trafegar em uma direção circular).
Não consigo lidar com a GUI na qual algum trabalho pode ser feito apenas em um thread estritamente serializado (o "thread principal") e outro trabalho só pode ser feito em qualquer thread, exceto o thread principal (os "threads de trabalho") e onde dados e mensagens precisam viajar em todas as direções entre N componentes (um gráfico totalmente conectado).
Na época em que deixei esse projeto para outro, havia problemas de impasse por toda parte. Ouvi dizer que, 2-3 meses depois, vários outros desenvolvedores conseguiram corrigir todos os problemas de conflito, a ponto de poderem ser enviados aos clientes. Eu nunca consegui descobrir o conhecimento que faltava.
Algo sobre o projeto: o número de IDs de mensagens (valores inteiros que descrevem o significado de um evento que pode ser enviado para a fila de mensagens de outro objeto, independentemente do encadeamento), chega a vários milhares. Seqüências de caracteres únicas (mensagens de usuário) também chegam a cerca de mil.
Adicionado
A melhor analogia que recebi de outra equipe (não relacionada aos meus projetos passados ou presentes) foi "colocar os dados em um banco de dados". ("Banco de dados" referente à centralização e atualizações atômicas.) Em uma GUI fragmentada em várias visualizações, todas em execução no mesmo "encadeamento principal" e todo o levantamento pesado não-GUI é feito em encadeamentos de trabalho individuais, os dados do aplicativo devem seja armazenado em um único local que atue como um banco de dados e deixe o "banco de dados" lidar com todas as "atualizações atômicas" que envolvem dependências de dados não triviais. Todas as outras partes da GUI lidam apenas com o desenho da tela e nada mais. As partes da interface do usuário podem armazenar em cache coisas e o usuário não notará se estiver obsoleto por uma fração de segundo, se for projetado corretamente. Esse "banco de dados" também é conhecido como "o documento" na arquitetura Document-View. Infelizmente, não, meu aplicativo realmente armazena todos os dados nas Views. Não sei por que foi assim.
Colaboradores:
(os colaboradores não precisam usar exemplos reais / pessoais. As lições de exemplos anedóticos, se você julgar credível, também serão bem-vindas.)