Wanna be Brilliant Full-Stack Developer

자바 동기와 비동기가 무엇인가? 본문

Some Memos/Java

자바 동기와 비동기가 무엇인가?

Flashpacker 2023. 3. 28. 21:15


동기와 비동기에 대해서 알아보자!

프로그래밍에서 동기라는것은 일의 순서가 있다라는걸 말한다.

프로그래밍에서 비동기라는건 일의 순서가 없다는 말이다.

 

예를 들어서 알아보자!

길동이가 있는데 길동이가 회사의 관리자이다.
길동이가 이제 일을 시킬것이다. 

꺽정이랑 보고랑 순신이한테 일을 시킬것이다.

그래서 처음에 일을 어떻게 시킬거냐면 동기적으로 일을 시켜보자!

일의 순서가 있다는 것인데

일의 순서가 있을떄 일을 어떻게 시키는가? 

무슨일을 시킬까?

일은 간단하다!

출판사에 가서 10부를 인쇄시키기를 시킬것이다!

일을 시키기 위해서 각각 꺽정이와 보고와 순신이에게 출판사에가서 10부를 인쇄해와 이렇게 시키는애가

길동이이다. 

길동이는 프로그램에서 CPU라고 한다. 관리자가 한명이다.

이때 일을 시키는데 실제로는 길동이 밖에 일을 못한다. 

CPU가 하나니까! 근데 일을 시킬것인데 스레드를 하나씩 내릴것이다.

길동이가 일을 시킬때 자바는 메인스레드 밖에 없는데?

꺽정이한테 10부를 인쇄해올래? 라고 일을 시켰다.

꺽정이한테 10부를 인쇄하는데 3초가 걸리는데 3초동안 길동이가 멍떄리고 대기를 한다.

그래서 길동이가 첫번째로 꺽정이가 10부 인쇄 끝낼떄까지 멍떄리고 대기한다.

그렇게 하다가 3초가 지나서 길동이가 일을 끝나면 그떄 다시

보고 한테 10 부인쇄를 시킨다. 이렇게 하면 보고는 또 3초동안 인쇄를 해야하는데

보고가 3초동안 인쇄를 할동안 길동이도 멍떄리고 대기를 한다.

보고가 3초뒤에 다했다고 하면 마지막으로 길동이가 순신이한테 10부 인쇄해오라고 시킨다.

그러면 순신이한테 일을 시키고 길동이는 또 멍떄리고 대기를 한다.

 

이게 머냐면 동기적 프로그래밍이다. 스레드가 없을떄 이렇게 일을 한다.

결국 자바에서는 왜 멍떄리고 대기하는가? 전부다 메인스레드가 일을 하기 떄문이다.

 

이거를 이제를 시나리오를 바꿔서 비동기적으로 일을 시켜보려고 한다.

길동이가 꺽정이한테 10부인쇄해라고 부탁할떄 10부 인쇄해 하라고 할때 어떤 스레드에게 일을 시키는가하면 새로운 스레드 1번에게 일을 시킨다.

이렇게 일을시키냐면 애가 3초가 걸려도 기다리지 않는다.

기다리지 않고 바로 보고에게 10부 인쇄하라고 새로운 스레드 2번이 한다.

동시다발적으로 일을 시킬 수 있다.

이렇게 되면 새로운 스레드한테 일을 시켰기 떄문에 꺽정이한테 일을 시키고 나서 

멍떄리고 대기하는것이 아니라 바로 보고한테도 순신이한테도 일을 시킨다.

순서대로 다하면 다했다고 응답이 올것이니 멍때리는 시간이 없다.

멍떄리는 시간이 없는것이 비동기적 실행이라고 한다.

 

애도 마찬가지로 CPU가 하나가 있는데 동기적 실행 입장에서는 꺽정도 보고도 순신이도

메인 스레드인데 비동기적 실행은 메인 스레드는 길동이 밖에 없고

나머지는 독립적인 스레드이다.

스레드가 총 4개가 있는것이다. 메인스레드 하나 새로운 스레드 3개!

보통 비동기적 실행은 언제하는가? 2가지 상황에서 한다.

첫번쨰는? 눈속임을 하고 싶을떄 쓴다.

예를 들어서 모니터 화면에 색칠을 할것인데 윗부분은 빨간색을 칠하고 아랫부분은 파란색을 칠하는데

그것을 동시에 칠하고 싶은데 CPU가 동기적이든 비동기적이든 CPU는 하나이다. 

그러면 비동기적으로 한다는것은 결국은 왔다갔다 하는것이기 떄문에 문맥교환이 일어나는 것이다.

그리고 애는 하나를 칠하고 밑에를 칠하고 이거를 굉장히 빠른속도로 하게되면

동시에 그리는것처럼 느껴진다. 속도가 굉장히 빠른 속도로 해서 동시에 그리는것처럼 느껴져도

전체적인 총합의 시간은 느려진다. 총합의 시간이 느리다라는건 어떤 뜻인가?

내가 빨간색을 다 그리고 파란색을 그리는 속도가 왔다갔다 하는것보다는 더 빠를것이다.

왔다갔다 하는것은 붓을 골라야하고 붓을 바꿔가면서 그려야하기 떄문에

붓을 바꾸는 시간이 걸린다. 

그래서 붓의 변경의 시간 떄문에 이시간떄문에 훨씬더 오래 걸린다.

붓을 안바꾸고 한번에 위에꺼 다 그리고 밑에 다그리고 가 이게 더 빠르다

그대신 동시에 그리는것처럼 눈속임은 안된다.

 

스레드는 동시에 그리는것처럼 눈속임을 할 수 있따.

 

2번쨰는 CPU는 연산장치이다. 그리고 메모리 공간은 저장 장치이다.

그러면 1부터 1억까지 더하기 연산을 한다고 해보자

이건 CPU가 하면 된다. 메모리가 할일이 없다.

근데 1부터 1억까지 더하기 연산을 하는것은 메모리가 할일이 없지만

내가 만약에 어떤 데이터를 다운받아야한다면?

만약에 이런 로직이 있다면? 첫번쨰로 할것은 1부터 1억까지 연산을 해야한다.

2번쨰는 통신으로 오늘 날씨가 어떤지 다운로드 받을 것이다.

3번쨰는 천부터 5천까지 더하기 연산을 한다고 해보자

CPU가 3가지 연산을 해야하는데 첫번쨰는 CPU가 하는것이 맞다.

두번쨰가 하는것은 CPU가 하는것이 아니라 메모리가 해야한다.

첫번쨰 일을 실행을 했다 그러면 끝났따.

두번쨰로 다운로드 하는 시간이 3초가 걸린다고 하면 다운로드를 누가하는가? 메모리에게 맡긴다.

메모리가 외부에서 통신을 해서 저 날씨 데이터를 다운 받으러 온다.

그러면 3초동안 기다렸다가 3초 후에 3번이 실행 된다.

3초동안 멍떄리는 시간이 생겼다. CPU가 멍때린다.

멍떄리는 시간을 줄이기 위해서 어떻게 하는가? 멍떄리지 않기 위해서는

2번쨰 연산 두번쨰 일을 다른애 한테 시킨다.

첫번쨰 1번은 메인스레드가 하고, 세번쨰도 메인 스레드가 하고 

두번쨰거를 누가 하는가? 스레드 1한테 시키면 메인 스레드가 멍떄리지 않고 

1부터 1억까지 연산을 하면 2번은 새로운 스레드에게 맡겨버리고

그리고 바로 내려가서 메인 스레드는 천부터 5천까지 연산을 해버린다.

이렇게 하면 메인 스레드가 안멍떄린다.

이렇게 하면 속도가 빨라진다.

그러면 눈속임의 효과가 있다.

 

2번쨰로는 어떤 효과가 있는가? 어떤일을 할떄 쓰는가?

CPU가 멍떄리는 시간을 없애주는 것이다.

 

언제없앨수 있는가? CPU가 일을 하지 않을떄

1번은 CPU가 일을 하고 2번은 메모리, 3번은 CPU가 일을 한다.

메모리가 일하는 2번을 다른 스레드가 하게 되면 스레드 1번이 멍떄리게 된다.

메인 스레드가 멍을 안떄리게 된다.

멍떄리는 것을 다른애한테 미루는 것이다.

이떄 스레드를 쓴다. 2가지 일을 하는것이다.

 

첫번쨰 효과 눈속임, 두번째 멍떄리는 시간을 없애 준다.

 

동기는 일의 순서가 있고 비동기는 일의 순서가 없다.

일의 순서가 있는 프로그램을 짜면 항상 기다리는 시간이 생기고

비동기로 프로그램을 짜면 기다리는 시간이 줄어들거나 없어질 수 있다.

그대신 비동기로 하면 자바에서는 스레드를 쓰게 되는데 스레드를 쓰게 되면

왔다갔다를 하게 되는 문맥교환을 하게 되면 컴퓨터가 부하가 많이 된다.