Back-end/이것이 자바다[신용권 한빛미디어] 65

[제네릭]

왜 제네릭을 사용해야 하는가? Java 5부터 제네릭(Generic) 타입이 새로 추가, 제네릭 타입을 이용함 으로써 잘못된 타입이 사용될수 있는 문제를 컴파일 과정에서 제거 제네릭은 컬렉션, 람다식, 스트림, NIO에서 널리 사용되므로 확실히 이해 API 도큐먼트를 보면 제네릭 표현이 많다, 제네릭은 클래스와 인터페이스, 메소드를 정의할때 타입(type)을 파라미터(parameter)로 사용할 수 있게함 타입 파라미터는 코드 작성시 구체적인 타입으로 대체 되어 다양한 코드 생성하도록 해줌 제네릭 코드의 장점 컴파일 시 강한 타입 체크를 할수 있다. -> 자바 컴파일러는 코드에서 잘못 사용된 타입 때문에 발생하는 문제점을 제거하기위해 제네릭 코드에 대해 강한 타입 체크를 한다. 실행 시 타입 에러가 나는..

스레드 풀

병렬 작업 처리가 많아지면 스레드 개수가 증가되고 그에 따른 스레드 생성과 스케줄링으로 인해 CPU가 바빠져 메모리 사용량이 늘어난다. 따라서 애플리케이션의 성능저하 된다. 갑작스런 병렬 작업의 폭증으로 인한 스레드의 폭증을 막으려면 스레드풀(ThreadPool)을 사용해야 한다. 스레드풀은 작업처리에 사용되는 스레드를 제한된 개수만큼 정해놓고 작업 큐 (Queue)에 들어노는 작업들을 하나씩 스레드가 맡아 처리한다 작업 처리가 끝난 스레드는 다시 작업 큐에서 새로운 작업을 가져와 처리한다. 그렇기 때문에 작업 처리 요청이 폭증되어도 스레드의 전체 개수가 늘어나지 않으므로 애플리케이션의 성능이 급격히 저하 되지 않는다. 자바는 스레드풀을 생성하고 사용할 수 있도록 java.util.concurrent 패..

스레드 그룹(ThreadGroup)

스레드 그룹은 관련된 스레드를 묶어서 관리할 목적으로 이용된다. JVM이 실행 되면 system 스레드 그룹을 만들고, JVM 운영에 필요한 스레드들을 생성해서 system 스레드 그룹에 포함시킨다 그리고 system의 하위 스레드 그룹으로 main을 만들고 메인 스레드를 main 스레드 그룹에 포함시킨다. 스레드는 반드시 하나의 스레드 그룹에 포함되는데, 명시적으로 스레드 그룹에 포함시키지 않으면 기본적으로 자신을 생성한 스레드와 같은 스레드 그룹에 속하게 된다. 우리가 생성하는 작업 스레드는 대부분 main 스레드가 생성하므로 기본적으로 main 스레드 그룹에 속하게 된다. 스레드 그룹 이름 얻기 현재 스레드가 속한 스레드 그룹의 이름을 얻고 싶다면 다음과 같은 코드를 사용 할 수 있다. Thread..

스레드 상태 제어

사용자는 미디어 플레이어에서 동영사을 보다가 일시 정지 시킬 수도 있고, 종료 시킬 수도 있다 일시 정지는 조금 후 다시 동영상을 보겠다는 의미이므로 미디어 플레이어는 동영상 스레드를 일시 정지 상태로 만들어야 한다 그리고 종료는 더 이상 동영상을 보지 않겠다는 의미 이다 미디어 플레이어는 스레드를 종료 상태로 만들어야 한다. 이와 같이 실행 중인 스레드의 상태를 변경하는 것을 스레드 상태 제어라고한다. 멀티 스레드 프로그램을 만들기 위해서는 정교한 스레드 상태 제어가 필요한데, 상태 제어가 잘못되면 프로그램은 불안정해져서 먹통이 되거나 다운된다. 멀티 스레드 프로그래밍이 어렵다고 하는 이유는 바로 여기에 잇다. 스레드를 잘 사용하면 약이 되지만, 잘못하용하면 치명적인 프로그램 버그가 되기 때문에 스레드..

스레드 상태

스레드 객체를 생성하고, start() 메소드를 호출하면 곧바로 스레드가 실행되는 것처럼 보이지만 사실은 실행 대기 상태가 된다. 실행 대기 상태란 아직 스케줄링이 되지 않아서 실행을 기다리고 있는 상태를 말한다. 실행 대기 상태에 있는 스레드 중에서 스레드 스케줄링으로 선택된 스레드가 비로서 CPU를 점유하고 run() 메소드를 모두 실행하기 전에 스레드 스케줄링에 의해 다시 실행 대기 상태로 돌아갈수 있다 그리고 실행 대기 상태에 있는 다른 스레드가 선택되어 실행 상태가 된다 이렇게 스레드는 실행 대기 상태와 실행 상태를 번갈아가면서 자신으 run() 메소드를 조금씩 실행 한다. 실행 상태에서 run() 메소드가 종료 되면, 더 이상 실행할 코드가 없기 때문에 스레드의 실행은 멈추게 된다 이를 종료 ..

동기화 메소드와 동기화 블록

공유 객체를 사용할 때의 주의 할 점 싱글 스레드 프로그램에서는 한 개의 스레드가 객체를 독차지해서 사용하면 됨 멀티 스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 하는 경우 이 경우, 스레드 A를 사용하던 객체가 스레드 B에 의해 상태가 변경 될 수 있기 때문에 스레드 A가 의도 했던 것과는 다른 결과를 산출 할 수도 있다. 이는 마치 여러 사람이 계산기를 함께 나눠 쓰는 상황과 같아서 사람 A가 계산기로 작업을 하다가 계산 결과를 메모리에 저장한 뒤 잠시 자리를 비웠을 때 사람 B가 계산기를 만져서 앞 사람이 메모리에 저장한 값을 다른 값으로 변경하는 것과 같다 그런 다음 사람 A가 돌아와 계산기에 저장된 값을 이용해서 작업을 진행한다면 결국 사람 A는 엉터리 값을 이용하게 된다 User1..

스레드 우선순위

멀티 스레드는 동시성(Concurrency) 병렬성(Parallelism) 으로 실행 동시성 멀티 작업을 위해 하나의 코어에서 멀티 스레드가 번갈아가며 실행하는 성질 병렬성 멀티 작업을 위해 멀티 코어에서 개별스레드를 동시에 실행하는 성질 싱글 코어 CPU를 이용한 멀티 스레드 작업은 병렬적으로 실행되는 것 처럼 보이지만 사실은 번갈아가며 실행하는 동시성 작업이다. 번갈아 실행하는 것이 워낙 빠르다 보니 병렬성으로 보일 뿐 스레드의 개수가 코어의 수보다 많을 경우, 스레드를 어떤 순서에 의해 동시성으로 실행할 것인가를 결정 이것을 스레드 스케줄링 스레드 스케줄링에 의해 스레드들은 아주 짧은 시간에 번갈아 가면서 그들의 run() 메소드를 조금씩 실행 자바의 스레드 스케줄링은 우선순위(Priority) 방..

작업 스레드 생성과 실행

멀티 스레드로 실행하는 애플리케이션을 개발하려면 먼저 몇 개의 작업을 병렬로 실행할지 결정하고 각 작업별로 스레드를 생성해야 한다. 어떤 자바 애플리케이션이건 메인 스레드는 반드시 존재하기 대문에 메인 작업 이외에 추가적인 병렬 작업의 수만큼 스레드를 생성하면 된다. 자바에서는 작업 스레드도 객체로 생성되기 때문에 클래스가 필요하다. java.lang.Thread 클래스를 직접 객체화 해서 생성해도 되지만, Thread 를 상속해서 하위 클래스를 만들어 생성할 수도 있다. Thread 클래스로부터 직접 생성 java.lang.Thread 클래스로부터 작업 스레드 객체를 직접 생성하려면 다음과 같이 Runnable을 매개값으로 갖는 생성자를 호출해야 한다 Thread thread = new Thread(R..

멀티 스레드 개념

프로세스와 스레드 프로세스(Process) : 운영체제에서는 실행 중인 하나의 애플리케이션 - 사용자가 애플리케이션을 실행하면 운영체제로부터 실행에 필요한 메모리를 할당받아 애플리케이션의 코드를 실행 하나의 애플리케이션은 다중 프로세스를 만들기도 한다 . Chrome 브라우저를 두개 실행 했다면 두 개의 Chrome 프로세스 생성 프로그램 -> 실행 프로세스 -> 실행 프로세스 멀티 태스킹 : 두 가지 이상의 작업을 동시에 처리하는 것, 운영체제는 멀티 태스킹을 할 수 있도록 CPU 및 메모리 자원을 프로세스마다 적절히 할당 , 병렬로 실행 워드로 문서작업을 하면서 동시에 윈도우 미디어 플레이로 음악을 들을수 있다. 멀티 태스킹은 꼭 멀티 프로세스를 뜻하지는 않는다. 한 프로세스 내에서 멀티 태스킹을 할..

java.time 패키지

자바 7이전 까지는 Date와 Calendar 클래스를 이용해서 날짜와 시간 정보를 얻을 수 있었다. Date 클래스의 대부분의 메소드는 Deprecated 되었고 , Date의 용도는 단순히 특정 시점의 날자 정보를 저장하는 역할만 한다 . Calendar 클래스는 날짜와 시간 정보를 얻기 에는 충분하지만, 날짜와 시간을 조작하거나 비교하는 기능이 불충분하다. 자바 8부터 날짜와 시간을 나타내는 여러가지 API를 새롭게 추가했다. 이 API는 java.util 패키지에 없고 별도로 java.time 패키지와 하위 패키로 제공 된다 패키지 설명 java.time 날짜와 시간을 나타내는 핵심 API인 LocalDate, LocalTime, LocalDateTime, ZonedDateTime을 포함하고 있다..