SpringBoot 를 실행 중에 웹 상에서 버튼을 이용하여
일련의 작업(임의의 테이블의 update 작업 , 일괄 Email 전송, Excel upload 등등)들을 껐다 켰다 할 수 있을까
라는 생각을 하게 되었고 Batch 와 Scheduler 를 이용해 보았지만 따로 제어하기가 힘들다고 생각됐다
그래서 Thread를 이용해보았고 내가 원하던 대로 동작은 하고 있지만
많은 작업을 시도해 보지 않아서 어디까지 뻗지 않고 가능한지 잘 모르겠다
TestThread.class
public class TestThread extends Thread{
public void run() {
while(true){
try {
// Test를 위해 2초마다 출력되도록 함
Thread.sleep(2000);
System.err.println("테스트 Thread 실행 중");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
TestController.class
@Controller
public class UserController {
// Test thread
TestThread tt = new TestThread();
@GetMapping("/login")
public String loginPage() throws Exception{
System.err.println("Login Page~~~~");
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
// 로그인 정보가 없으면 loginPage 로 있으면 / 메인페이지로
if (authentication instanceof AnonymousAuthenticationToken)
return "loginPage";
return "redirect:/";
}
// Thread 실행 메서드
@GetMapping("/start")
public void start() throws Exception{
System.err.println("Thread 시작");
tt.start();
}
// thread 종료 메서드
@GetMapping("/stop")
public void stop() throws Exception{
System.err.println("Thread 종료");
tt.interrupt();
}
}
실행
localhost:9090/start 를 했다가 다시 login 화면으로 돌아왔을때
log가 어떻게 찍히는지를 확인
Thread 실행에는 run() 과 start() 가 있는데 둘 다 실행을 하지만 동작 원리가 다르다
run() 은 단순히 메서드를 호출하는 것이며 Single Thread로 하나의 thread 가 끝나야 다음 thread 가 실행된다
start() 는 새로운 Thread가 작업을 실행하게 되어 새로운 호출 스택을 생성한 뒤 run()을 호출하여 Multi Thread 로 동시에 실행된다(동시라고는 했지만 실제론 동시에 진행되지는 않는다)
오류
localhost:9090/stop 을 하고 다시 /start를 하니 IllegalThreadStateException 오류가 발생했다
해당 Exception 을 찾아보니 한번 실행이 종료된 Thread 는 다시 실행 할 수 없고
다시 실행을 시켰을 때 IllegalThreadStateException 가 발생한다고 한다
방법은 start 메서드를 사용할 때마다 Thread를 생성해주면 된다
@Controller
public class UserController {
// Test thread
TestThread tt = new TestThread();
->>>
@Controller
public class UserController {
// Test thread
TestThread tt;
Controller 상단에서 선언하고 객체를 생성했었는데
객체를 선언만 시킨다
@GetMapping("/start")
public void start() throws Exception{
System.err.println("Thread 시작");
tt = new TestThread();
tt.start();
}
/start 메서드에서 객체를 생성하면 Thread가 동작을 다하고 끝나거나
중간에 종료를 시킨 후 에도 /start 메서드를 통해 다시 동작 할 수 있다
웹상에서는 url을 통해 기능이 동작하기 때문에 동시에 여러 작업을 할 수 없다
만약 사이트에서 이메일을 전송한다고 했을 때
한 두명~ 수십명 정도야 조금만 기다리면 바로 전송이 되지만
100만명에게 이메일을 작성하고 전송을 한다면
전송 동작이 끝날 때까지 아무것도 할 수 없고 멍하니 모니터만 바라봐야 할 것이다
이런 상황 혹은 지속적으로 어떤 동작이 계속 실행되어 있어야 하는 상황에 사용 할 수 있을까 하여 글을 남겨 둔다
'개발 > Java' 카테고리의 다른 글
[Java] 단방향 암호화 하기 - SHA256 (0) | 2023.05.26 |
---|---|
[Java] cURL - ProcessBuilder 사용하기 (0) | 2023.05.24 |
[Java] ExcelUpload - 파일 읽고 DB에 insert 하기 (0) | 2023.05.11 |
[Java] google json-simple 사용하기 (0) | 2023.05.08 |
[Java] org.json 사용하기 (0) | 2023.05.08 |
댓글