Whiteship's Note


Collection과 Thread 3

Java : 2007.05.02 20:37


이전 글인 "Collection과 Thread 2"에서 공부할 것으로 분류했던 클레스들의 정체를 밝히는 것으로 본 시리즈의 막을 내리려고 합니다.

총정리 및 발표는 이번주 AJN 정모에서 하게 됩니다. 혹시라도 차후 Agile Java 3기에 참여하실 분들 중에서 관심있으신 분들께서는 이메일 주소 남겨주시면 특별히 무료로 이번 정모에 참석하실 수 있도록 안내 메일 보내 드리겠습니다.

그럼 다시 본론으로 돌아가서 Java 5.0에서 Concurrent Collection이라는 것들을 추가했습니다. 그것들이 바로 이전 글에서 잘 모르겠다고 했던 클래스들입니다.

Concurrent Collections

CopyOnWriteArrayList

ConcurrentSkipListSet, CopyOnWriteArraySet

ConcurrentLinkedQueue

ConcurrentHashMap, ConcurrentSkipListMap


이녀석들이죠. 기존에 존재하던 Syncronized Collection을 사용하면 모든 메소드들이 전부 키를 사용하여 롹킹되기 때문에 완전한 Thread-Safety는 보장이 되지만 그에 따른 비용이 발생하게 됩니다. 데드락이 발생할 수 있는 여지가 생기며, 여러 쓰레드가 대기 상태에 머무를 수 있습니다.

하지만 Concurrent Collection은 멀티 쓰레드 환경에서 하나의 데이터에 여러 쓰레드가 동시에 읽는 것을 허용하면서도 쓰기 작업은 하나의 쓰레드만 하도록 롹킹을 Fine-grained하게 적용했습니다. 따라서 기존의 Syncronized Collection에 비해 퍼포먼스가 좋을 것이며 주된 차이점으로는 iteration할 때 fail-fast가 발생하지 않는 다는 것입니다.

ConcurrentHashMap 은 동기화 된 Map 구현체를 대체 하기 위해 만들어졌습니다.
ConcurrentSkipListMap 은 동기화 된 SortedMap 을 대체 하기 위해 Java 6.0 에 추가 됐습니다.
CopyOnWriteArrayList 는 동기화 된 List 구현체를 대체 하기 위해 만들어졌습니다.
ConcurrentSkipListSet 는 동기화 된 SortedSet 을 대체 하기 위해 Java 6.0 에 추가 됐습니다.
CopyOnWriteArraySet 는 동기화 된 Set 구현체를 대체 하기 위해 만들어졌습니다.
ConcurrentLinkedQueue 는 동기화 된 Queue 구현체를 대체 하기 위해 만들어졌습니다.

ConcurrentHashMap 살펴보기

위에서 언급했다시피 모든 메소드에 롹킹을 하는 Syncronized Collection과는 다르게 읽기 작업을 하는 메소드는 롹킹을 걸지 않고 쓰기 작업을 하는 메소드에 롹킹을 걸어서 특정 수의 쓰기 작업한 동시적으로 처리할 수 있도록 합니다.

또한 ConcurrentModificationException을 발생시키지 않습니다. 콜렉션이 수시로 변할 수 있다는 가정하에 Fail-fast 검증 방식을 사용하지 않는 것입니다. 어차피 멀티 쓰레드 상황이면 당연히 수시로 변할 수 있다는 가정을 가지고 간다면 타당한 예외 처리 방법이기도 합니다.

장점만 있는 것은 아닙니다. 콜렉션이 수시로 변할 수 있다는 가정하에 동기화(weakly consistent)를 제공하고 있기 때문에 size 나 isEmpty 메소드의 정확함을 보장하지 못합니다.

또 다른 단점으로는 exclusive access(상호배제) 를 제공하지 못합니다. 상호배제는 운영체제 시간에 들었던 것으로 멀티프로세스에 관한 이야기에서 나온 것인데 고스란히 쓰레드에도 적용할 수 있겠습니다. 즉 여러 쓰레드가 하나의 공유자원에 접근하고자 할 때 하나의 쓰레드가 공유자원에 접근하여 작업하는 중에는 다른 모든 쓰레드는 중단된 상태여야 하는데 이것을 상호배제라고 합니다.(그걸 구현한 방법중 하나가 key를 사용한 locking이고 모니터랑 세마포어 같은 것들도 있습니다.)

상호배제를 사용하지 못하는 단점을 보완할 수 있는 인터페이스를 제공합니다. 바로 ConcurrentMap 인터페이로서 put-if-absent, remove-if equal, replace-if-equal 같은 메소드를 제공합니다.

사용자 삽입 이미지

이 클레스와 같은 원리로 다른 ConcurrencyXXX 클레스들도 똑같이 동작합니다.

CopyOnWriteArrayList 살펴보기

동기화 된 List 구현체들 대신으로 사용할 수 있으며 iteration 할 때 콜렉션을 복사 하거나 메소드들에 롹을 걸 필요를 없애주면서 동시성을 제공하는 클레스입니다.

콜렉션에 쓰기 작업을 Thread-safety를 보장하기 위해 매번 수정된 콜렉션의 복사체를 제공하여 해결합니다. 따라서 ConcurrencyModificationException을 발생시키지 않으며(snapshop을 사용하기 때문이죠.), iteration을 하는 모든 쓰레드는 동기화 할 필요가 없으며 복사체를 가질 순간의 콜렉션의 상태를 기반으로 정확하게 동작하게 됩니다.

하지만 콜렉션이 수정 될 때 마다 복사하는 비용이 발생하며 특히 덩치가 큰 콜렉션의 경유 콜렉션에 수정하는 작업보다 iteration하는 작업이 많을 때 이 클레스의 사용이 적당하겠습니다.

이 클레스와 같은 원리로 CopyOnWriteArraySet 클레스도 똑같이 동작합니다.

'Java' 카테고리의 다른 글

때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
Factory Method vs Constructor  (0) 2007.05.18
효율적인 문자열 연결 방법  (2) 2007.05.18
Collection과 Thread 3  (4) 2007.05.02
Collection의 Fail-fast  (0) 2007.05.01
숨어있는 Iterator 찾기  (0) 2007.05.01
Reflections on Java Reflection  (2) 2007.04.25
Collection과 Thread 2  (0) 2007.04.24
Collection과 Thread 1  (0) 2007.04.24
top


Collection과 Thread 2

Java : 2007.04.24 18:07


Thread Safe 하냐 안하냐 기준으로 Collection 클레스들을 나눠 봤습니다. Java 6.0 API 기준으로 나눴기 때문에 새로 눈에 띄는 클레스들과 잘 모르겠는 클레스들도 포함되어 있습니다.

Thread safe collections

Vector(Stack)

HashTable

BlockingQueue implementations(ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue)

BlockingDeque implementation (LinkedBlockingDeque)

 

Not thread safe collections

LinkedList, ArrayList(AttributeList, RoleList, RoleUnresolvedList)

EnumSet, HashSet, TreeSet

ArrayDeque, PriorityQueue

EnumMap, HashMap, IdentityHashMap, TreeMap, WeakHashMap

 

뭔가 이상한 것들(공부해야 할 것들)

CopyOnWriteArrayList

ConcurrentSkipListSet, CopyOnWriteArraySet

ConcurrentLinkedQueue

ConcurrentHashMap, ConcurrentSkipListMap


흠.. 대체 CopyOnWrite 와 Concurrency, ConcurrencySkip 은 어떤 뜻일까요? 역시 다음 글에서 알아보도록 하겠습니다.

'Java' 카테고리의 다른 글

효율적인 문자열 연결 방법  (2) 2007.05.18
Collection과 Thread 3  (4) 2007.05.02
Collection의 Fail-fast  (0) 2007.05.01
숨어있는 Iterator 찾기  (0) 2007.05.01
Reflections on Java Reflection  (2) 2007.04.25
Collection과 Thread 2  (0) 2007.04.24
Collection과 Thread 1  (0) 2007.04.24
Thread와 Collection 관련 링크 모음  (0) 2007.04.19
예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
Java 6.0의 Collection  (4) 2007.03.22
private에 대한 착각  (2) 2007.03.05
top


Collection과 Thread 1

Java : 2007.04.24 16:15


사용자 삽입 이미지
출처 : http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html

Java 6 API에서 Collection을 살펴 보면 다음과 같은 문구가 있습니다.
It is up to each collection to determine its own synchronization policy.
Collection의 상위 레벨에서 thread와 관련된 정책은 없고 동기화에 대한 책임은 각각의 구현체들마다 다를 수 있다는 것을 알려줍니다.

Collection 인터페이스를 구현한 클래스들은 다음과 같습니다.
AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, AbstractSet, ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList, BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons, LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector
그럼 과연 이중에서 어떤 클래스들은 Thread-safe 할까요? 그건 다음 포스팅에서 살펴보겠습니다.

'Java' 카테고리의 다른 글

Collection과 Thread 3  (4) 2007.05.02
Collection의 Fail-fast  (0) 2007.05.01
숨어있는 Iterator 찾기  (0) 2007.05.01
Reflections on Java Reflection  (2) 2007.04.25
Collection과 Thread 2  (0) 2007.04.24
Collection과 Thread 1  (0) 2007.04.24
Thread와 Collection 관련 링크 모음  (0) 2007.04.19
예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
Java 6.0의 Collection  (4) 2007.03.22
private에 대한 착각  (2) 2007.03.05
Stream 인코딩 바꾸기  (0) 2007.02.28
top


Java 6.0의 Collection

Java : 2007.03.22 08:44


원문 : What is new in Java 6.0 Collections API?
번역 : Java 6.0 컬렉션 API에 어떤 변화가 있는가?


'Java' 카테고리의 다른 글

Reflections on Java Reflection  (2) 2007.04.25
Collection과 Thread 2  (0) 2007.04.24
Collection과 Thread 1  (0) 2007.04.24
Thread와 Collection 관련 링크 모음  (0) 2007.04.19
예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
Java 6.0의 Collection  (4) 2007.03.22
private에 대한 착각  (2) 2007.03.05
Stream 인코딩 바꾸기  (0) 2007.02.28
SWT 프로그램 실행하기  (0) 2007.02.21
제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
GC관련 아티클  (0) 2007.01.19
top


Collections - <list />

Spring/Chapter 3 : 2007.03.08 23:06


<list /> 엘리먼트는 Java의 List에 대응 합니다. 다음과 같이 설정할 수 있습니다.
    <bean id="keesun3" class="beanConfiguration.Member">
        <property name="wishList">
            <list>
                <value>NDS</value>
                <value>Wii</value>
                <value>WOW</value>
            </list>
        </property>
    </bean>
순서대로 NDS가 첫번째 WOW가 세번째 입니다.

    @Test public void list(){
        Member keesun = (Member) bf.getBean("keesun3");
        List<String> wishList = keesun.getWishList();
        assertEquals("NDS", wishList.get(0));
        assertEquals("Wii", wishList.get(1));
        assertEquals("WOW", wishList.get(2));
    }
위의 테스트 코드로 확인할 수 있습니다.

번외로.. Eclipse 자동 완성 기능 정말 좋네요.
사용자 삽입 이미지



'Spring > Chapter 3' 카테고리의 다른 글

3.5. Customizing the nature of a bean  (0) 2007.03.10
Singleton & Prototype  (0) 2007.03.09
3.4. Bean scopes  (0) 2007.03.09
Autowiring  (0) 2007.03.09
Collection Merging  (0) 2007.03.09
Collections - <list />  (0) 2007.03.08
Inner beans  (0) 2007.03.08
idref 엘리먼트  (0) 2007.03.08
Constructor Injection 할 때 인자 구분  (0) 2007.03.08
Setter Injection & Constructor Injection  (0) 2007.03.08
3.3. Dependencies  (0) 2007.03.08
top


Generic과 다형성

Java : 2007.01.05 14:27


사용자 삽입 이미지
위와 같은 계층 구조를 가진 클래스를 사용하는 콜렉션을 다음과 같이 코딩을 합니다.

public class AnimalCollection {

       @Test

       public void feedingAnimalList(){

             List<Animal> animals = new ArrayList<Animal>();

             animals.add(new Animal());

             animals.add(new Dog());

             animals.add(new Cat());

             feedAnimals(animals);

       }

 

       private void feedAnimals(List<Animal> animals) {

             for(Animal animal : animals){

                    animal.eat();

             }

       }

}


결과를 확인하면 다음과 같이 원하는 대로 돌아간 것을 확인할 수 있습니다.
동물이 먹습니다.
강아지가 먹습니다.
고양이가 먹습니다.

다형성을 이용하기 위해서 Dog List를 만들고 이 리스트도 밥을 먹이기 위해서 feedAnimals메소드를 사용해 봅시다.

       @Test

       public void feedingDogList(){

             List<Dog> dogs = new ArrayList<Dog>();

             dogs.add(new Dog());

             dogs.add(new Dog());

             dogs.add(new Dog());

             feedAnimals(dogs);

       }

       private void feedAnimals(List<Animal> animals) {

             for(Animal animal : animals){

                    animal.eat();

             }

       }

위와 같이 코딩을 하면 컴파일에러가 발생하는 것을 알 수 있습니다.

즉 List<Animal> animals 매개변수를 가진 feedAnimals메소드에 List<Dog> 타입이 들어갈 수 없다는 것입니다. 들어가지 못하는 이유는 위험하기 때문입니다. 만약 feedAnimals에서 dogs를 받아 들인다고 했을 때 feedAnimals에서 dogs에 Cat 타입의 객체를 넣을 수도 있을 겁니다.

       private void feedAnimals(List<Animal> animals) {

             animals.add(new Cat());

       }

위와 같은 일이 아예 벌어지지 않도록 컴파일 에러를 내준다고 합니다.

배열과의 차이점 보기


참조 : Head First Java

'Java' 카테고리의 다른 글

GC관련 아티클  (0) 2007.01.19
Generics 번외 - 겉모습만 보곤 알 수 없슴.  (2) 2007.01.17
Generics  (2) 2007.01.17
Eclipse 단축키 모음  (6) 2007.01.11
Generic과 다형성 2탄  (4) 2007.01.05
Generic과 다형성  (0) 2007.01.05
자바 검은 띠에 도전해 보시길~  (2) 2006.12.31
Hiding Method  (0) 2006.12.31
Overriding - covariant return type  (6) 2006.12.31
LinkedList vs ArrayList  (6) 2006.12.22
Agile Java 소스코드(10장까지..)  (8) 2006.12.21
top


Arrays and Hashes

RUBY/Manual : 2006.10.02 18:13


Arrays and Hashes


Ruby의 array와 hash는 인덱스가 있는 collection입니다. 둘 다 객체를 담아 두고 key를 사용하여 접근하는 콜렉션입니다. array에서 key는 정수이지만 hash는 어떤 객체도 key가 될 수 있습니다. 둘 모두 새로운 요소를 추가할 때 커기제 됩니다. array에 접근을 하는게 보다 효율 적이지만 hash는 보다 유연함을 제공합니다. 어떤 array이나 hash들도 여러 타입의 객체를 담아 둘 수 있습니다. 이 말은 하나의 array에 정수, 문자열, 실수를 담을 수 있다는 것입니다.


[ ] 이 괄호 사이에 요소들을 나열 하는 array literal을 사용하여 새로운 배열을 생성하고 초기화 할 수 있습니다. array 객체를 가지고 객체에 있는 각각의 요소들에 [] 안에 index를 사용하여 접근할 수 있습니다. 다음의 예에서 봅시다.

a = [ 1, 'cat', 3.14 ]   # array with three elements
# access the first element
a[0] »1
# set the third element
a[2] = nil
# dump out the array
a »[1, "cat", nil]


array 객체의 생성자를 사용하여 생성하거나 요소들이 없는 비어있는 괄호 [] 를 사용하여 배열을 생성할 수도 있습니다. Array.new .
empty1 = []
empty2 = Array.new


단어들의 배열을 생성할 때 "" 와 , 를 사용하기가 매우 번거로울 수 있는데 이 때 사용하기 편한 것이 있습니다. 바로 %w 입니다. 다음과 같이 사용할 수 있습니다.

a = %w{ ant bee cat dog elk }
a[0] »"ant"
a[3] »"dog"


Ruby의 hash는 배열과 비슷합니다. hash는 [] 말고 {} 이 괄호를 사용합니다. 반드시 하나의 요소에는 두 개의 객체가 제공되어야 합니다. 하나는 key 하나는 value입니다.


예를들어, 악기들을 오케스크라 위치에 따라 매핑하고 싶다면 다음과 같이 할 수 있습니다.

instSection = {  'cello'     => 'string',  
'clarinet'  => 'woodwind',  
'drum'      => 'percussion',  
'oboe'      => 'woodwind',  
'trumpet'   => 'brass',  
'violin'    => 'string'}


Hash는 array와 같이 [] 괄호를 사용하여 index화 됩니다.

instSection['oboe'] »"woodwind"
instSection['cello'] »"string"
instSection['bassoon'] »nil


마지막 예가 보여주듯이 hash에 해당하는 key가 없는 경우에 기본적으로 nil을 반환합니다. 하지만 가끔은 여러분이 원하는 기본값을 반환하도록 하고 싶을 것입니다. 예를 들어 해당하는 key가 몇 번 출현하는지 카운팅하는 hash의 경우 기본값을 0으로 하고 싶을 것입니다. 이것은 hash를 생성할 때 생성자에 기본값을 인자로 넘겨 주는 방식으로 할 수 있습니다.

histogram = Hash.new(0)
histogram['key1'] »0
histogram['key1'] = histogram['key1'] + 1
histogram['key1'] »1


배열과 해쉬 객체는 매우 유용한 메소드들을 많이 가지고 있습니다. 33page와 278page~317page에 걸쳐 이 메소드들에 대해 자세하게 나와있습니다.

'RUBY > Manual' 카테고리의 다른 글

Reading and 'Riting  (0) 2006.11.04
Blocks and Iterators  (0) 2006.11.03
Regular Expressions  (0) 2006.10.05
Control Structures  (0) 2006.10.04
Arrays and Hashes  (0) 2006.10.02
Some Basic Ruby  (0) 2006.09.26
Ruby Is an Object-Oriented Language  (0) 2006.09.17
Roadmap  (0) 2006.09.16
top