
: 두 가지 이상의 대상(함수, 애플리케이션 등)이 서로 시간을 맞춰 행동하는 것
A -> A // 시작 시간 또는 종료 시간이 일치하면 동기
B -> B
A, B 쓰레드가 동시에 작업을 시작하는 경우
ex) CyclicBarrier
메서드 리턴 시간(A)과 결과를 전달받는 시간(B)이 일치하는 경우
A -> A // A가 끝나는 시간과 B가 시작하는 시간이 같으면 동기
B -> B
ex) Synchronized, BlockingQueue
: 동기와 반대로, 대상이 서로 시간을 맞추지 않는 것
-> 호출하는 함수가 호출되는 함수에게 작업을 맡겨 놓고 신경 쓰지 않는 것
int number = 20;
Thread newThread = new Thread(() -> {
System.out.println("Factorial of " + number + " is: " + factorial(number));
});
newThread.start();
: 직접 제어할 수 없는 대상의 작업이 끝날 때까지 제어권을 넘겨주지 않는 것
-> 호출하는 함수가 작업을 요청했을 때 작업 처리가 완료될 때까지 아무 일도 하지 못한 채 기다리는 것
ex)
1. InvokeAndWait(): Wait for the Event Dispatcher thread to execute code.
2. InputStream.read(): It blocks until input data is available, throws an exception, or detects the end of the stream.
3. ServerSocket.accept(): Listen to inbound Java socket connection and blocks until a connection has been made.
4. CountDownLatch.await(): Cause the current thread to wait until the latch counts to zero unless the thread is interrupted.
: 블로킹과 반대로, 직접 제어할 수 없는 대상의 작업 처리 여부와 상관 없음
-> 호출하는 함수가 작업을 요청한 후 작업 처리 완료 여부와 상관없이 바로 자신의 작업을 할 수 있음
동기 vs 비동기 : 순서와 결과(처리)의 관점
블로킹 vs 논블로킹 : 제어의 관점
-> 전혀 다른 관점이므로 서로 독립적으로 봐야함
ExecutorService es = Executors.newCachedThreadPool();
String res = es.submit(() -> “Hello Async”).get();
es.submit(()->”Hello Async") : 비동기
get() : 동기, 블로킹
- ExecutorService : 병렬 작업 시 여러 개의 작업을 효율적으로 처리하기 위해 제공되는 라이브러리
-Executors.newCachedThreadPool() : 필요에 따라 새 스레드를 작성하는 스레드 풀을 작성하지만 사용 가능한 경우 이전에 구성된 스레드를 재사용함. 이러한 풀은 일반적으로 많은 단기 비동기 작업을 실행하는 프로그램의 성능을 향상시킴. 실행 호출은 사용 가능한 경우 이전에 생성된 스레드를 재사용함. 사용 가능한 기존 스레드가 없으면 새 스레드가 작성되어 풀에 추가됨. 60 초 동안 사용되지 않은 스레드는 종료되고 캐시에서 제거됨. 따라서 오랫동안 유휴 상태 인 풀은 리소스를 소비하지 않음.
->해당 클래스에서 ExecutorService에 작업을 submit하게 되면 ExecutorService 내부에서 해당 작업을 내부적으로 스케쥴링하면서 적절하게 일을 처리함.
-Runnable : return값이 없는 쓰레드, Callable : return값이 존재하는 쓰레드
물건을 주문하는 데 걸리는 시간 0.5초
주문 완료 후 메일을 발송하는 데 걸리는 시간 2초
동기 응답 속도 = 2.5초
비동기 응답 속도 = 0.5 + 𝛼 (메일 발송 Async)
device = IO.open()
data = device.read()
print(data)
read() 메서드(application)가 리턴하는 시간과 kernel에서 결과를 가져오는 시간이 일치함 => 동기
커널의 작업이 완료될 때까지 대기함(데이터를 읽을 때까지 기다림) => 블로킹
System.out.print(“출력하고 싶은 메시지를 입력해주세요 : “);
final Scanner sc = new Scanner(System.in);
String msg = sc.nextLine();
System.out.println(“블로킹 동기”);
System.out.println(msg);
입력 끝나는 시간과 출력하는 시간이 일치함 => 동기
입력이 끝날 때까지 대기하다가 제어권을 넘겨 받음 => 블로킹
앞의 결과를 받으면 바로 다른 작업 실행함 => 동기
제어권을 계속 가지고 있으면서 결과 끝났냐고 계속 물어봄 => 논블로킹
동기 / 블로킹 과 비슷함
-> 그럼 언제 쓸까? 게임에서 맵을 넘어갈 때처럼 해당 데이터를 가져올 때까지 유저에게 정보의 로드율을 보여줄 때
바로 하지 않아도 되는데 굳이 제어권을 못 받고 있는 것
어차피 나중에 할 거지만 상사가 이메일 보내줄 때까지 기다리고 있는거라고 생각하면 되나...
fetch(‘url’, option).then((response) => {return response.json();}).then((data) => {something(data);});
Sync VS Async, Blocking VS Non-Blocking
Synchronization in Java
Asynchronous Programming in Java
Blocking Methods in Java