우리는 컴퓨터를 구입할 때 컴퓨터 CPU의 코어와 스레드 수에 특별한 주의를 기울이는 경우가 많습니다. 이것은 종종 컴퓨터의 속도를 결정하기 때문에
, 이 모든 것은 작업 관리자에서 찾을 수 있습니다.
이때 멀티스레드 연산에 노출되더라도 스레드가 무엇인지 의심할 수 있다.
Baidu 백과사전에 따르면 스레드 (영어: thread)는 운영 체제가 작업 스케줄링을 수행할 수 있는 가장 작은 단위입니다 . 이는 프로세스 에 포함되며 프로세스 의 실제 작동 단위 입니다 . 스레드는 프로세스 의 단일 순차적 제어 흐름을 의미합니다.여러 스레드가 프로세스에서 동시에 실행될 수 있으며 각 스레드는 서로 다른 작업을 병렬로 수행합니다. Unix System V 및 SunOS 에서는 경량 프로세스(lightweight process)라고도 하지만 경량 프로세스는 커널 스레드(kernel thread), 사용자 스레드(user thread)는 스레드라고 합니다.
그렇다면 멀티스레딩은 언제 사용해야 할까요?
이렇게 하면 각 스레드를 가장 효율적으로 사용할 수 있습니다.
스레드 동시성 안전성이란 무엇입니까?
동시 작업을 처리할 때 여러 쓰레드가 같은 리소스에서 동작하기 때문에 연산 시간이 시차를 두지 않아 메모리에서 연산이 반복되어 데이터 혼란과 보안 문제가 발생한다.
예를 들면 다음과 같습니다. 각 스레드에 대한 작업, 즉 num에 1000배를 추가했습니다.
스레드 스택 작업 단계: 힙 메모리에서 num 가져오기 -->> num 복사본을 스레드 스택에 복사 -->> num++ 작업 수행
——>>num을 반환하고 힙 메모리의 num에 할당합니다.
이것이 올바른 것처럼 보이지만 반드시 하나의 스레드만 동시에 힙 메모리에서 num을 가져오는 것은 아닙니다.
여러 스레드가 가져오면 num++ 연산이 반복되어 최종 숫자가 3000++ 미만이 되고 데이터가 잘못됩니다.
일반적인 상황:
이 문제를 어떻게 해결할 수 있습니까?
결국, 이 데이터가 은행의 금액을 나타낸다면 그것이 잘못되는 것을 원하지 않을 것입니다! ! !
잠금 사용( 동기화됨) :
코드 블록을 동기화하고, 리소스를 잠그고, 현재 모니터 잠금을 보유하고 있는 스레드만 리소스에 액세스하도록 허용합니다.
다음과 같이 이해할 수 있습니다. 스레드가 힙 메모리에서 num을 복사하면 힙 메모리가 일시적으로 "잠겨" 액세스할 수 없습니다.
스레드가 num 작업을 완료하고 num을 힙 메모리에 할당한 경우에만 다른 스레드가 힙 메모리에 액세스하기 위해 계속 경쟁하도록 "잠금 해제" 됩니다 .
이렇게 하면 작업이 반복되지 않고 데이터가 잘못되지 않으며 동시에 경쟁 액세스 메커니즘으로 인해 작업 속도가 크게 가속화됩니다.
예는 다음과 같습니다.
작업 클래스:
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);//检验结果
}
}
스레드 클래스:
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++;
}//给堆内存上锁,保证线程安全
}
}//线程操作方式
}
결과는 다음과 같습니다.
모든 것이 정상입니다! ! !
리소스 잠금을 제거하면 다음과 같습니다.
즉, 데이터 오류:
동시 작업의 경우 멀티스레딩을 사용하면 효율성을 크게 높일 수 있지만 스레드 안전 문제에 큰 주의를 기울여야 합니다!