Quando compramos um computador, geralmente prestamos atenção especial em quantos núcleos e threads a CPU do computador possui. Porque isso geralmente determina a velocidade do computador
, e tudo isso pode ser encontrado no gerenciador de tarefas.
Neste momento, mesmo que você tenha sido exposto a operações multi-threaded, você pode ter dúvidas sobre o que é um thread.
De acordo com a Enciclopédia Baidu: Thread (Inglês: thread) é a menor unidade que o sistema operacional pode realizar o agendamento da operação . Ele está incluído no processo e é a unidade operacional real no processo . Um thread refere-se a um único fluxo sequencial de controle em um processo . Vários threads podem ser executados simultaneamente em um processo e cada thread executa tarefas diferentes em paralelo. No Unix System V e SunOS , também é chamado de processos leves (processos leves), mas os processos leves referem-se a encadeamentos do kernel (encadeamentos do kernel) e encadeamentos do usuário (encadeamentos do usuário) são chamados de encadeamentos.
Então, quando precisamos usar multithreading?
Isso permite o uso mais eficiente de cada encadeamento.
Então, o que é segurança de simultaneidade de threads?
Ao lidar com tarefas concorrentes, como várias threads operam no mesmo recurso, o tempo de operação não é escalonado, o que torna a operação na memória repetida, resultando em confusão de dados e causando problemas de segurança.
Por exemplo: Organizamos tarefas para cada thread, ou seja, somando 1000 vezes a num.
Etapas da operação da pilha de threads: obtenha num da memória heap -->> copie a cópia num para a pilha de threads -->> execute a operação num++
——>>Retorne num e atribua-o a num na memória heap.
Isso parece estar em ordem, mas notamos que não necessariamente apenas um thread obtém num da memória heap ao mesmo tempo.
Se vários threads o obtiverem, a operação num++ será repetida, de modo que o número final seja menor que 3000++ e os dados estejam errados.
Situações comuns:
E como resolvemos esse problema?
Afinal, se esse dado representa o valor que está no seu banco, você não vai querer que esteja errado! ! !
Usando fechaduras ( sincronizadas) :
Sincronize blocos de código, bloqueie recursos e permita apenas que threads atualmente mantendo bloqueios de monitor acessem recursos
Pode ser entendido como: quando uma thread copia num na memória heap, a memória heap é temporariamente "bloqueada" e não pode ser acessada.
Somente quando o thread concluir a operação de num e atribuir num à memória heap, ele será "desbloqueado" para que outros threads continuem a competir para acessar a memória heap.
Isso pode não apenas garantir que a operação não seja repetida, os dados não estarão errados e, ao mesmo tempo, devido ao mecanismo de acesso competitivo, a velocidade da tarefa será bastante acelerada.
Os exemplos são os seguintes:
Classe de tarefa:
public class Task{
static int num=0;//静态变量,处于堆内存中
public static void main(String[] args) {
Task tt = new Task();
Thread t1=new Thread(new Threadsy(tt));
t1.start();
Thread t2=new Thread(new Threadsy(tt));
t2.start();
Thread t3=new Thread(new Threadsy(tt));
t3.start();//创建并启动三个线程
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException e) {
throw new RuntimeException (e);
}//阻塞,直到线程全部完成,便于得到最终结果
System.out.println(tt.num);//检验结果
}
}
Classe Thready:
public class Threadsy implements Runnable {
Task tt = new Task();
public Threadsy(Task tt) {
this.tt = tt;
}//构析方法,便于取堆内存中的num。
static Object object = new Object();//值得注意的是,Object要保证是静态变量,存在堆内存中,才可以通过它“锁住”堆内存的num
public void run() {
for (int i = 0; i < 1000; i++) {
synchronized (object/*只能“锁”对象*/) {
tt.num++;
}//给堆内存上锁,保证线程安全
}
}//线程操作方式
}
Os resultados são ambos:
tudo normal! ! !
E se removermos o bloqueio de recurso:
ou seja, erro de dados:
Para tarefas simultâneas, o uso de multithreading pode melhorar muito a eficiência, mas preste muita atenção aos problemas de segurança do thread!