Thread

자바 5에서 제공하는 Executor 프레임워크와 스레드 풀을 통해 자바는 스레드의 힘을 높은 수준으로 끌어올렸다. 바로 태스크 제출과 실행을 분리하여 제공했기 때문이다. 우리는 스레드 풀을 만들어 놓고, 스레드풀에 태스크만 제출하면 된다! 스레드의 문제점 ㅠㅠ 운영체제에 직접 접근한다. 생성비용이 비싸다. 운영체제 스레드의 숫자는 제한되어 있으며, 이 수를 초과해버리면 자바 애플리케이션이 예상치 못한 방식으로 크래시될 수 있다. (계속 스레드를 생성하는 상황은 절대 나오면 안된다.) 즉, 개발자가 직접 스레드를 다루기에는 신경쓸게 많다는 것이다. 만약에 다양한 기기에서 실행될 수 있는 프로그램을 만든다면 미리 하드웨어 스레드 개수를 추측하지 않는 것이 좋다. 주어진 프로그램에서 사용할 최적의 자바 스레..
콜백 방식의 작업 완료 통보 자바스크립트를 조금해보면 콜백방식이 익숙할 것이다. 자바에서도 스레드 작업이 완료되면 특정 메소드를 자동 실행할 수 있는 콜백 방식을 이용할 수 있다.블로킹 방식 콜백방식ExecutorService는 콜백을 위한 기능을 제공하지 않는다. Runnable 클래스를 작성할 때 콜백 기능을 구현할 수 있는데 java.nio.channels.CompletionHandler를 이용해서 구현할 수 있다.(NIO 패키지 안에 존재, 비동기 통신에서 콜백 객체를 만들때 사용된다.) CompletionHandler callback = new CompletionHandler(){ @Override public void completed(V result, K attachment){} // 작업이..
블로킹 방식의 작업 완료 통보_2 작업 처리 결과를 외부 객체에 저장 스레드가 작업 처리를 완료하고 외부 Result 객체에 저장하면, 애플리케이션에서 Result 객체를 사용하여 작업을 진행할 수 있다. (대개 Result 객체는 공유객체가 되어, 두 개 이상의 스레드 작업을 취합할 목적으로 이용된다.)ExecutorService.submit(Runnable task, V result) 에서 V가 Result 타입이 된다. class Task implements Runnable{ Result result; Task(Result result){this.result = result;} @Override public void run(){ // 작업내용, result 저장 } } class Result{ //..
블로킹 방식의 작업 완료 통보_1 ExecutorService의 submit() 메소드는 Runnable, Callable 작업을 스레드 풀의 작업 큐에 저장하고 즉시 Future 객체를 리턴한다.Future 객체는 작업이 완료될 때까지 기다렸다가(블로킹되었다가) 최종 결과를 얻는데 사용된다. (그래서 Future 객체를 지연 완료(pending completion)객체라고 한다.)Future의 get() 메소드를 호출하면 스레드가 작업을 완료할 때까지 블로킹되었다가 작업을 완료하면 처리 결과를 리턴한다. (블로킹을 사용하는 작업 완료 통보 방식) 주의할 점은 Future의 get() 메소드는 스레드가 작업이 완료될때까지 블로킹되므로 다른 코드를 실행할 수 없다는 것이다. 따라서 get() 메소드를 호출..
2019.03.14 - [프로그래밍 노트/JAVA] - [JAVA] 블로킹 방식의 작업 완료 통보_1 (스레드풀_2) 2019.03.16 - [프로그래밍 노트/JAVA] - [JAVA] 블로킹 방식의 작업 완료 통보_2 (스레드풀_3) 2019.03.16 - [프로그래밍 노트/JAVA] - [JAVA] 콜백 방식의 작업 완료 통보 (스레드풀_4) 스레드풀 병렬 작업 처리가 많아지면 스레드 수가 증가되고 그에 따른 스레드 생성과 스케줄링으로 인해 CPU가 바빠져서 메모리 사용량이 늘어난다. (애플리케이션 성능 저하) 따라서 스레드의 폭증을 막으려면 스레드풀(ThreadPool)을 사용해야 한다. 스레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐(Queue)에 들어오는 작업들을 ..
스레드 그룹 스레드 그룹(ThreadGroup)은 관련된 스레드를 묶어서 관리할 목적으로 이용된다. JVM이 실행되면 system 스레드 그룹을 만들고, JVM 운영에 필요한 스레드들을 생성해서 system 스레드 그룹에 포함시킨다. 그리고 system의 하위 스레드 그룹으로 main을 만들고 메인 스레드를 main 스레드 그룹에 포함시킨다. 모든 스레드는 그룹을 갖으며 스레드 그룹을 명시적으로 선언하지 않으면 자신을 생성한 스레드와 같은 그룹에 속한다. public class ThreadInfoExample { public static void main(String[] args) { AutoSaveThread autoSaveThread = new AutoSaveThread(); autoSaveThrea..
interrupt() 메소드를 이용하여 스레드를 정지시키기 스레드는 자신의 run() 메소드가 모두 실행되면 자동적으로 종료된다. 하지만 실행중인 스레드를 즉시 종료해야 할 때도 필요하다. (stop() 메소드가 존재하였으나, 종료시 자원들이 불안전한 상태로 남겨지기 때문에 deprecated 되었다.)interrupt() 메소드는 스레드가 일시 정지 상태에 있을 때 InterruptedException 예외를 발생 시킨다.이것을 이용하면 run() 메소드를 정상 종료시킬 수 있다. 스레드가 실행 대기 또는 실행 상태에 있을 때 interrupt() 메소드가 실행되면 즉시 InterruptedException 예외가 발생하지 않고, 스레드가 미래에 일시 정지 상태가 되면 InterruptedExcepti..
스레드간 협업(wait, notify, notifyAll) 경우에 따라 두 스레드가 교대로 번갈아가며 실행해야 할 경우가 있다. (정확한 교대작업이 필요한 경우, 한 스레드가 작업이 끝나며 상대방 스레드의 일시정지를 풀어주고 자신은 일시정지로 만들어야 한다.)공유객체 를 사용하여 두 스레드가 작업할 내용을 각각 동기화 메소드로 구분해 놓은 후 한 스레드가 작업이 완료되면 notify()메서드를 호출한다.notify() => 일시 정지 상태에 있는 다른 스레드를 실행 대기 상태로 만듬 wait() => 스레드를 일시 정지 상태로 만듬위 두 메서드는 Thread 클래스가 아닌 Object 클래스에 선언된 메소드이므로 모든 공유 객체에서 호출이 가능하다. (동기화블록에서만 사용 가능) 스레드 작업 내용을 동기..
다른 스레드의 종료를 기다림(join()) 스레드는 다른 스레드와 독립적으로 실행되는 것이 일반적이지만, 다른 스레드가 종료될 때까지 기다리다가 실행되야되는 경우가 발생할 수 있다.예를 들어 B라는 스레드는 계산을하는 스레드이고, A라는 스레드는 B스레드가 계산이 끝나면 그 결과값을 가지고 로직을 처리해야하는 상황이다.이 와같은 상황은 아래와 같은 코드를 이용해 구현할 수 있다.(join() 이용) ThreadA{ threadB.start(); // ThreadB 실행 (실행순서 1) threadB.join(); // 일시정지 ...ThreadA의 로직 수행 ; // (실행순서 3) } ThreadB{ run(){ // ThreadB 작업 실행(실행순서 2) } } ThreadA가 ThreadB의 joi..
동기화 메소드와 동기화 블록 공유 객체를 사용할 때 주의할 점멀티 스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 하는 경우가 있다.이 경우, 스레드 A를 사용하던 객체가 스레드 B에 의해 상태가 변경될 수 있기 때문에 스레드 A가 의도했던 것과는 다른 결과를 산출할 수도 있다. public class User1 extends Thread{ private Calculator calculator; @Override public void run() { calculator.setmemory(100); } public void setCalculator(Calculator calculator) { this.setName("User1"); this.calculator = calculator; } } pub..
깡냉쓰
'Thread' 태그의 글 목록