본문 바로가기
[Java Concurrency] 중단 및 종료 #1 [Java Concurrency] 중단 및 종료 #1 - 작업이나 스레드를 안전하고 빠르고 안정적으로 멈추게 하는 것은 어려운 일이다. 더군다나 자바에는 스레드가 작업을 실행하고 있을 때 강제로 멈추도록 하는 방법이 없다. 대신 인터럽트(interrupt)라는 방법을 사용할 수 있게 되어 있는데, 인터럽트는 특정 스레드에게 작업을 멈춰달라고 요청하는 형태이다. 실제 상황에서 특정 스레드나 서비스를 "즉시" 멈춰야 할 경우는 거의 없고, 강제로 종료하면 공유되어 있는 여러 가지 상태가 비정상적인 상태에 놓일 수 있기 때문에 스레드 간의 협력을 통한 접근 방법이 올바르다. 다시 말해, 작업이나 서비스를 실행하는 부분의 코드를 작성할 때 멈춰달라는 요청을 받으면 진행 중이던 작업을 모두 정리한 다음 종료하도록.. 2017. 4. 25.
[Effective Java] 독자적인 직렬화 형태의 사용을 고려하자 [Effective Java] 독자적인 직렬화 형태의 사용을 고려하자 - 클래스를 설계할 때 클래스가 Serializable 을 구현하면서 기본 직렬화 형태를 사용한다면, 나중에 함부로 버릴 수 없고, 그 직렬화 형태를 계속 유지해야 할 가능성이 높다. - 적합 여부를 우선적으로 고려해보고 기본 직렬화 형태를 수용하자. 기본 직렬화 형태는 유연성, 성능, 정확성의 관점에서 타당하다는 결정이 섰을 때 사용해야 한다. 일반적으로 말하면, 우리가 독자적인 직렬화 형태를 설계한다고 할 때 하게될 인코딩과 대부분 같은 경우에만 기본 직렬화 형태를 사용해야 한다. - 이상적인 객체 직렬화 형태는 그 객체가 표현하는 논리적 데이터만 포함한 것이다. - 기본 직렬화 형태는 객체의 물리적 표현이 논리적인 내용과 동일할 .. 2017. 3. 23.
[Effective Java] Serializable 인터페이스를 분별력 있게 구현하자. [Effective Java] Serializable 인터페이스를 분별력 있게 구현하자. - 객체 직렬화(object serialization) API 는 객체를 바이트 스트림으로 인코딩하고, 인코딩된 바이트 스트림으로부터 객체를 복원(디코딩) 하는 프레임워크이다. - 객체를 바이트 스트림으로 인코딩하는 것을 직렬화(serializing)이라 하고, 그 반대의 절차를 역직렬화(deserializing)이라고 한다. - 객체가 일단 직렬화되면, 인코딩된 객체는 향후에 역직렬화 하기 위해 하나의 실행 중인 VM 에서 다른 VM 으로 전송되거나 디스크에 저장될 수 있다. 직렬화는 원격 통신을 위한 표준 통신 회선 수준의 객체 표현을 제공한다. 직렬화 프록시는 effective java 의 직렬화 주제중 가장 .. 2017. 3. 21.
[Effective Java] 스레드 그룹을 사용하지 말자. [Effective Java] 스레드 그룹을 사용하지 말자. - 스레드, 락, 모니터에 더하여 스레드 시스템에서 제공하는 기본 추상체가 스레드 그룹(thread group) 이다. 스레드 그룹은 원래 보안을 목적으로 애플릿을 격리시키는 메커니즘으로 구상되었다. 그러나 실제로는 그런 기대를 충족시키지 못해 자바 보안 모델의 표준에서 언급되지 않을 정도로 쇠약하다. - 스레드 그룹은 기능이 별로 없다. 단지 Thread 클래스의 기본 메소드들을 여러 스레드가 포함된 그룹에 일괄로 한번에 적용할 수 있게 해준다. 그런 기본 메소드들 중 상당 수는 이미 사용금지 되었으며 남은 메소드들은 사용되는 경우가 드물다. - ThreadGroup 클래스의 API 메소드는 스레드 안전 관점에서도 빈약하다. 하나의 스레드 그.. 2017. 3. 20.
[Effective Java] 스레드 안전을 문서화 하자. [Effective Java] 스레드 안전을 문서화 하자. - 클래스 행동을 문서화하지 않으면, 프로그래머는 가정에 의존해서 그 클래스를 사용해야 한다. 만일 그런 가정들이 잘못되면, 그로 인한 프로그램은 불충분한 동기화나 과도한 동기화를 하게 될 것이다. 어떤 경우든, 심각한 에러가 유발될 수 있다. - 메소드 선언부의 synchronized 변경자는 메소드의 상세 구현 부분이지 외부로 제공되는 API 가 아니다. 즉 Javadoc 에 synchronized 가 공개되지 않는다. synchronized 변경자가 있다는 것이 스레드 안전을 문서화하기에 충분한 것은 아니다. 동시적 사용을 안전하게 하려면, 해당 클래스가 어떤 수준의 스레드 안전을 지원하는지 명확하게 문서화해야 한다. - 다음은 스레드 안전.. 2017. 3. 14.
[Effective Java] 실패 원자성을 갖도록 노력하자 [Effective Java] 실패 원자성을 갖도록 노력하자 - 일반적으로 호출된 메소드가 실행에 실패하더라도 객체 상태는 메소드 호출 전과 같아야 한다. 이런 특성을 갖는 메소드를 실패 원자성(failure atomic) 메소드라 한다. - 가장 간단한 방법은 불변 객체로 설계하는 것이다. 객체가 불변이면 실패 원자성과는 아예 무관하다. - 가변 객체를 처리하는 메소드의 경우에 실패 원자성을 성취하는 가장 보편적인 방법은 연산 수행 전에 매개 변수의 유효성을 검사하는 것이다. - 실패 원자성을 성취하는 더 좋은 방법은, 객체를 변경하는 코드 부분에 앞서 실패할 수 있는 코드 부분이 실행되도록 연산 순서를 조정하는 것이다. - 또 다른 방법은 ( 흔하지 않지만 ) 연산 도중에 발생하는 실패를 가로채는 복.. 2017. 3. 3.
[Effective Java] 표준 예외를 사용하자 [Effective Java] 표준 예외를 사용하자 - 기본 예외를 재사용하면 여러 가지 장점이 있다. 프로그래머들이 이미 익숙해진 내용과 일치하기 때문에 우리 API 를 배우고 사용하기 쉽게 해준다. 생소한 예외를 사용하지 않으므로 코드를 이해하기 쉽다. 메모리 사용도 적게하고 클래스를 메모리로 로딩하는 시간도 줄어든다. - 자주 재사용되는 형태의 exception 은 IllegalArgumentException, IllegalStateException, NullPointerException, UnSupportedOperationException 등이 있다. API, Effective JAVA, IllegalArgumentException, illegalstateexception, NullPointer.. 2017. 2. 24.
[Java] What is "CopyOnWriteArrayList" [Java] What is "CopyOnWriteArrayList" http://developer.android.com/reference/java/util/concurrent/CopyOnWriteArrayList.html - Thread-safe 한 random access list. - Read 는 block 이 걸리지 않는다. addAll, clear 와 같은 aggregate operation 은 atomic 하다. - Iterator 를 사용할 때는 copy 본을 사용하기 때문에 ConcurrentModificationException 이 절대 발생하지 않는다. 대신 Iterator 가 최근 state 를 항상 반영하는 것은 아니다. - Iterator 가 copy 본이기 때문에 iterator .. 2017. 2. 22.
[Effective Java] 복구 가능 상황에서는 checked 예외를 사용하고, 런타임 예외는 프로그램 에러에 사용하자. 복구 가능 상황에서는 checked 예외를 사용하고, 런타임 예외는 프로그램 에러에 사용하자. - 자바 언어는 다음 세 종류의 예외를 던질 수 있다. checked exception, runtime exception, error - 메소드 호출자가 당연히 예외 복구를 할 수 있는 상황에서는 checked 예외를 사용하자. checked 예외를 던지면 그 메소드 호출자가 catch 문에서 예외를 처리하거나 또는 외부로 넘겨야 한다. API 사용자가 checked 예외와 만났다는 것은, 그런 상황을 복구하라는 지시를 그 API 설계자로부터 받은 것이다. - unchecked exception 인 runtime exception 과 error 는 catch 할 필요가 없고, 일반적으로 catch 해서도 안 된.. 2017. 2. 21.
반응형