CRC = Cyclic Redundancy Check
데이터 오류 검출 알고리즘
파일 내용을 계산해서 고유 숫자(체크섬)를 만들어냄
예)
파일 A → CRC = 12345678
파일 B → CRC = 98765432
파일 내용이 1바이트라도 바뀌면 CRC 값 완전히 달라짐
그래서 파일 지문이라고 부름
파일 분리보관/백업 시스템에서 매우 중요함
SHA256 알고리즘 - 보안/암호 목적, 속도 매우 느림
MD5 알고리즘 - 보안(구형), 속도 느림
CRC32 알고리즘 - 오류검출 목적, 속도 매우 빠름
파일 백업에서는 보안 필요 없음. 깨졌는지만 확인하면 됨
그래서 CRC32 = 속도 빠른 무결성 검사
대용량 파일 시스템에서 표준처럼 사용됨.
private long crc32(File file) throws Exception {
// CRC32 객체 생성
// CRC32 = 해시 계산기
CRC32 crc = new CRC32();
// 파일을 8KB씩 읽기
// 파일을 한 번에 다 읽으면 메모리 터짐 -> 나눠서 읽음
byte[] buffer = new byte[8192];
int read;
// 파일 읽기 전용 스트림으로 통로 연결
try (FileInputStream fis = new FileInputStream(file)) {
// 파일을 8KB씩 계속 읽음
while ((read = fis.read(buffer)) != -1) {
// 파일 내용 전부 읽으면서 CRC 계산기에 계속 누적
// 파일 전체 -> 하나의 숫자로 변환됨.
crc.update(buffer, 0, read);
}
}
return crc.getValue();
}
멀티 스레드에서 사용됨 (싱글 스레드여도 사용됨)
스레드 인터럽트 의미 : 이 작업을 멈춰야함 신호 표시
예 )
Thread.currentThread().interrupt();
현재 인터럽트 상태라고 표시 남김
어떤 스레드가 작업 중이라고 가정
Thread.sleep(10000); // 10초 쉬기
근데 서버에서 서버 종료, 작업 취소 버튼 클릭, 스케줄러 중단, 앱 강제 종류 준비 같은 일들이 발생하면 다른 스레드가 작업 중단하라고 말함
이게 바로 thread.interrupt();
인터럽트 = 작업 중단 요청 신호
강제 종료 x
멈춰 요청 o
그런데 sleep 중에 interrupt가 들어오면 InterruptedException 발생
try {
Thread.sleep(chunkDelayMs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
Java가 sleep 이 InterruptedException을 발생시키는 순간 인터럽트 상태를 자동으로 지워버림 (자동으로 false 로 바뀜)
Thread.currentThread().interrupt(); 로 상태 복원
전체 흐름
외부 스레드
↓ interrupt()
현재 스레드 (sleep 중)
↓
InterruptedException 발생
↓
Java가 인터럽트 플래그 삭제
↓
catch 진입
↓
Thread.currentThread().interrupt(); ← 복구
↓
상위 코드가 확인 가능
↓
스레드 정상 종료
sleep 중 서버 종료하면
JVM 종료 시그널
-> 스케줄러 스레드에 interrupt() 호출
-> sleep() 에서 InterruptedException 발생
-> catch에서 플래그 복원
-> 스프링 스케줄러 내부가 플래그를 보고 종료 인식
즉 이 메서드를 호출한 스프링 스케줄러가 인터럽트 플래그를 보고 정상적으로 스레드를 종료하도록 플래그를 복원해두는 것