Recentemente, tentei acessar uma caixa de texto de um thread (que não seja o thread da interface do usuário) e uma exceção foi lançada. Ele dizia algo sobre o "código não ser seguro para threads" e, por isso, acabei escrevendo um delegado (exemplo do MSDN ajudou) e ligando para ele.
Mas mesmo assim eu não entendi direito por que todo o código extra era necessário.
Atualização: Terei algum problema sério se verificar
Controls.CheckForIllegalCrossThread..blah =true
multithreading
thread-safety
definition
Vivek Bernard
fonte
fonte
Race-Condition
Respostas:
Eric Lippert tem um bom post intitulado O que você chama de "thread safe"? sobre a definição de segurança de threads, conforme encontrado na Wikipedia.
3 coisas importantes extraídas dos links:
Definitivamente vale a pena ler!
fonte
No mais simples dos termos, threadsafe significa que é seguro ser acessado a partir de vários threads. Quando você está usando vários threads em um programa e cada um deles tenta acessar uma estrutura ou local de dados comum na memória, várias coisas ruins podem acontecer. Então, você adiciona um código extra para evitar essas coisas ruins. Por exemplo, se duas pessoas estavam escrevendo o mesmo documento ao mesmo tempo, a segunda pessoa a salvar substituirá o trabalho da primeira pessoa. Para torná-lo seguro, é necessário forçar a pessoa 2 a aguardar que a pessoa 1 conclua sua tarefa antes de permitir que a pessoa 2 edite o documento.
fonte
A Wikipedia tem um artigo sobre segurança de threads.
Esta página de definições (você precisa pular um anúncio - desculpe) define assim:
Um encadeamento é um caminho de execução de um programa. Um único programa encadeado terá apenas um encadeamento e, portanto, esse problema não ocorre. Praticamente todos os programas da GUI têm vários caminhos de execução e, portanto, threads - existem pelo menos dois, um para processar a exibição da GUI e entregar a entrada do usuário e pelo menos um para executar as operações do programa.
Isso é feito para que a interface do usuário ainda seja responsiva enquanto o programa estiver trabalhando descarregando qualquer processo de execução longa para qualquer thread que não seja da interface do usuário. Esses encadeamentos podem ser criados uma vez e existirem durante toda a vida útil do programa, ou apenas criados quando necessários e destruídos quando terminados.
Como esses encadeamentos geralmente precisam executar ações comuns - E / S de disco, saída de resultados na tela etc. - essas partes do código precisam ser escritas de forma que possam lidar com a chamada de vários encadeamentos, geralmente em o mesmo tempo. Isso envolverá coisas como:
fonte
Simplesmente, thread safe significa que uma instância de método ou classe pode ser usada por vários threads ao mesmo tempo sem que ocorram problemas.
Considere o seguinte método:
Agora, o segmento A e o segmento B gostariam de executar AddOne (). mas A começa primeiro e lê o valor de myInt (0) em tmp. Agora, por algum motivo, o planejador decide interromper o encadeamento A e adiar a execução para o encadeamento B. O encadeamento B agora também lê o valor de myInt (ainda 0) em sua própria variável tmp. O segmento B termina o método inteiro, portanto, no final, myInt = 1. E 1 é retornado. Agora é a vez do Tópico A novamente. O segmento A continua. E adiciona 1 ao tmp (tmp era 0 para o segmento A). E, em seguida, salva esse valor em myInt. myInt é novamente 1.
Portanto, nesse caso, o método AddOne foi chamado duas vezes, mas como o método não foi implementado de maneira segura para threads, o valor de myInt não é 2, conforme o esperado, mas 1 porque o segundo thread leu a variável myInt antes da conclusão do primeiro thread. atualizando-o.
Criar métodos seguros de encadeamento é muito difícil em casos não triviais. E existem algumas técnicas. Em Java, você pode marcar um método como sincronizado, isso significa que apenas um encadeamento pode executar esse método em um determinado momento. Os outros threads aguardam na fila. Isso torna um encadeamento de método seguro, mas se houver muito trabalho a ser feito em um método, isso desperdiçará muito espaço. Outra técnica é 'marcar apenas uma pequena parte de um método como sincronizado'criando uma trava ou semáforo e bloqueando essa pequena parte (geralmente chamada de seção crítica). Existem até alguns métodos implementados como thread-less safe, o que significa que eles são criados de tal maneira que vários threads podem percorrê-los ao mesmo tempo, sem nunca causar problemas; esse pode ser o caso quando apenas um método executa uma chamada atômica. Chamadas atômicas são chamadas que não podem ser interrompidas e só podem ser feitas por um encadeamento de cada vez.
fonte
No mundo real, o exemplo para o leigo é
Suponhamos que você tenha uma conta bancária na Internet e em serviços bancários móveis e sua conta tenha apenas US $ 10. Você efetuou o saldo da transferência para outra conta usando o mobile banking e, enquanto isso, fazia compras online usando a mesma conta bancária. Se essa conta bancária não for segura, o banco permitirá que você realize duas transações ao mesmo tempo e, em seguida, o banco irá à falência.
Threadsafe significa que o estado de um objeto não muda se simultaneamente vários threads tentarem acessar o objeto.
fonte
Você pode obter mais explicações no livro "Concorrência Java na Prática":
fonte
Um módulo é seguro para threads se garantir que pode manter seus invariantes em face do uso multithread e simultâneo.
Aqui, um módulo pode ser uma estrutura de dados, classe, objeto, método / procedimento ou função. Parte do código com escopo básico e dados relacionados.
A garantia pode potencialmente ser limitada a determinados ambientes, como uma arquitetura específica da CPU, mas deve ser válida para esses ambientes. Se não houver delimitação explícita de ambientes, geralmente é considerado que é válido para todos os ambientes que o código possa ser compilado e executado.
Os módulos inseguros de thread podem funcionar corretamente sob uso simultâneo e com thread múltiplo, mas isso geralmente depende mais de sorte e coincidência do que de um design cuidadoso. Mesmo se algum módulo não quebrar para você, ele pode quebrar quando movido para outros ambientes.
Erros de multiencadeamento geralmente são difíceis de depurar. Alguns deles acontecem apenas ocasionalmente, enquanto outros se manifestam agressivamente - isso também pode ser específico do ambiente. Eles podem se manifestar como resultados sutilmente errados ou impasses. Eles podem atrapalhar as estruturas de dados de maneiras imprevisíveis e fazer com que outros erros aparentemente impossíveis apareçam em outras partes remotas do código. Pode ser muito específico da aplicação, por isso é difícil fornecer uma descrição geral.
fonte
Segurança de thread : um programa seguro de thread protege seus dados contra erros de consistência de memória. Em um programa altamente multiencadeado, um programa seguro de encadeamento não causa efeitos colaterais com várias operações de leitura / gravação de vários encadeamentos nos mesmos objetos. Diferentes threads podem compartilhar e modificar dados do objeto sem erros de consistência.
Você pode obter segurança de encadeamento usando a API de simultaneidade avançada. Esta página de documentação fornece boas construções de programação para garantir a segurança do encadeamento.
Os objetos de bloqueio oferecem suporte a idiomas de bloqueio que simplificam muitos aplicativos simultâneos.
Os executivos definem uma API de alto nível para iniciar e gerenciar threads. As implementações de executores fornecidas pelo java.util.concurrent fornecem gerenciamento de conjunto de encadeamentos adequado para aplicativos de grande escala.
Coleções simultâneas facilitam o gerenciamento de grandes coleções de dados e podem reduzir bastante a necessidade de sincronização.
As variáveis atômicas possuem recursos que minimizam a sincronização e ajudam a evitar erros de consistência de memória.
O ThreadLocalRandom (no JDK 7) fornece geração eficiente de números pseudo-aleatórios a partir de vários encadeamentos.
Consulte java.util.concurrent e java.util.concurrent.atomic pacotes também para outras construções de programação.
fonte
Você está trabalhando claramente em um ambiente WinForms. Os controles WinForms exibem afinidade de segmento, o que significa que o segmento no qual eles são criados é o único segmento que pode ser usado para acessá-los e atualizá-los. É por isso que você encontrará exemplos no MSDN e em outros lugares demonstrando como organizar a chamada de volta no thread principal.
A prática normal do WinForms é ter um único thread dedicado a todo o trabalho da interface do usuário.
fonte
Eu acho que o conceito de http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 é o que eu costumo considerar como threading inseguro, que é quando um método tem e depende de um efeito colateral, como uma variável global.
Por exemplo, eu vi código que formatou números de ponto flutuante como string, se dois deles são executados em threads diferentes, o valor global de decimalSeparator pode ser permanentemente alterado para '.'
fonte
Para entender a segurança das linhas, leia as seções abaixo :
fonte