컬렉션4 : ICollection 인터페이스 :: C# 인트로[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

C# 인트로
[1]
등록일:2008-03-27 20:04:04 (0%)
작성자:갤러리정
제목:컬렉션4 : ICollection 인터페이스

7.4 ICollection 인터페이스

 

ICollection 인터페이스는 IEnumerable 상속하기 때문에 기본적으로 나열의 속성을 가지고 있습니다. 그리고, Collection이라는 그대로 집합적인 개념을 가지고 있습니다. 다음은 ICollection 상속 구조를 보여주고 있습니다.

 

그림 7-3 ICollection 인터페이스의 상속 구조

 

ICollection 인터페이스에서 제공하는 기능은 집합적인 개념과 동기화 지원을 위한 기능들입니다. C# 컬렉션류라면 당연히 상속해야 하는 아주 대표적인 인터페이스입니다. 위의 상속 구조에서 있듯이 ICollection IEnumerable 상속하였다는 것도 잊지 마시기 바랍니다. 다음은 ICollection에서 이용할 있는 속성과 메서드입니다.

 

ICollection 인터페이스 속성

int Count

·   컬렉션의 객체 수를 반환한다. , 컬렉션 내에 얼마나 많은 객체가 있는지 알아낸다.

bool IsSynchronized

·   다중 스레드된 액세스를 위해 컬렉션에 대한 액세스(Access) 동기화한 경우 true 반환한다. 컬렉션이 동기화되는지에 따라서 쓰레드 안전성이 있는지 검사한다.

object SyncRoot

·   SyncRoot 속성은 스레드에서 컬렉션에 대한 액세스를 동기화하기 위해 사용할 있는 객체를 반환한다.

·   CLR 자동으로 어떤 .NET 형식 인스턴스라도 동기화루트(SyncRoot) 되도록 한다.

·   SyncRoot 하나 이상의 코드 문장이 동시에 스레드에 의해서만 실행되는 것을 확실하게 하기 위해 잠그거나 해제할 있다.

·  ICollection.SyncRoot 실행하면 항상 적절한 SyncRoot 객체를 반환한다.

 

ICollection 인터페이스 메서드

void CopyTo(Array array, int index)

·   지정한 배열 위치부터 컬렉션의 요소(Element) 배열로 복사한다.

 

 

다음의 예제는 컬렉션에 접근하는 방법을 보여주고 있습니다. 물론, 배열에 접근하고 있지만 배열은 기본적으로 Array 클래스를 상속하고 있기 때문에 IColleciton 구현하고 있는 상태입니다.

&

ICollectionSyncTest.cs

Ü ICollection 테스트하는 예제

using System;
using System.Collections;
using System.Threading;

public class 
ICollectionSync{
  
private Int32[ ] intArr = {1,2,3,45678910
};
  
public void 
SyncRun(){
    ICollection c = intArr; 

    //배열은 Array 상속 -> IColleciton으로 캐스팅 가능
    
IEnumerator e = c.GetEnumerator();
    
while
(e.MoveNext()) {
      Console.Write((
int)e.Current +"\t"
);
      
try
{
        Thread.Sleep(
20
);
      }
catch
{ }
    }
    Console.WriteLine(
"
요소갯수:{0} ", c.Count);
  }
//class

public class 
ICollectionSyncTest{
  
public static void 
Main() {
    ICollectionSync ics = 
new 
ICollectionSync();
    
//3
개의 스레드 생성
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
  } 
//main
//class

C:\C#Example\07>csc ICollectionSyncTest.cs

C:\C#Example\07>ICollectionSyncTest

1       1       1       2       2       2       3       3       3       4

4       4       5       5       5       6       6       6       7       7

7       8       8       8       9       9       9       10      10      10

요소갯수:10

요소갯수:10

요소갯수:10

 

ICollectionSync 클래스의 멤버필드로 Int32 배열을 선언한 SyncRun() 메서드 내에서 ICollecton으로 캐스팅하고 있습니다.

 

private Int32[ ] intArr = {1,2,3,4, 5, 6, 7, 8, 9, 10};

ICollection c = intArr; // 배열을 ICollection 인터페이스로 캐스팅

 

생성된 ICollection c에서 Enumerator 얻어내기 위해서 GetEnumerator() 호출한 열거자를 이용해서 모든 데이터를 출력하고 있습니다.

 

IEnumerator e = c.GetEnumerator();

while(e.MoveNext()) {

Console.Write((int)e.Current +"\t");

}

위의 예제에서는 3개의 스레드를 생성하여 각각 SynRun() 메서드를 스레드에 할당합니다. 그리고, Start() 메서드를 호출하여 3개의 스레드를 실행하고 있습니다.

 

new Thread(new ThreadStart(ics.SyncRun)).Start();

new Thread(new ThreadStart(ics.SyncRun)).Start();

new Thread(new ThreadStart(ics.SyncRun)).Start();

 

SynRun() 메서드 내부에서는 ICollectionSync 클래스 내의 배열에 동시에 접근하고 있습니다. 하지만, 여기서는 어떠한 동기화도 처리하지 않았습니다.

 

그림 7-4 컬렉션에서의 동기화 문제

 

동기화를 보장하고 있지 않기 때문에 각각의 스레드들이 동시에 접근하고 있습니다. 하지만, 이러한 접근에 동기화를 가미하면 전혀 다른 결과를 가져 있습니다.

 

다음의 예제는 앞의 예제에서 동기화 부분을 추가한 예제입니다.

 

&

ICollectionSyncTest1.cs

Ü ICollection 동기화를 테스트하는 예제

using System;
using System.Collections;
using System.Threading;

public class 
ICollectionSync{
  
private Int32[ ] intArr = {1,2,3,45678910
};
  
public void 
SyncRun(){
    ICollection c = intArr; 

    //배열은 Array 상속 -> IColleciton으로 캐스팅 가능
    
lock(c.SyncRoot){
      IEnumerator e = c.GetEnumerator();
      
while
(e.MoveNext()) {
        Console.Write((
int)e.Current +"\t"
);
        
try
{
          Thread.Sleep(
20
);
        }
catch
{ }
      }
      Console.WriteLine(
"
요소갯수:{0} ", c.Count);
    } 
//lock
  
}
//class

public class 
ICollectionSyncTest1{
  
public static void 
Main() {
    ICollectionSync ics = 
new 
ICollectionSync();
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
    
new Thread(new 
ThreadStart(ics.SyncRun)).Start();
  } 
//main
//class

C:\C#Example\07>csc ICollectionSyncTest1.cs

C:\C#Example\07>ICollectionSyncTest1

1       2       3       4       5       6       7       8       9       10

요소갯수:10

1       2       3       4       5       6       7       8       9       10

요소갯수:10

1       2       3       4       5       6       7       8       9       10

요소갯수:10

 

예제의 결과를 비교해 보시면 동기화에 대한 느낌을 정확하게 이해하실 있을 것입니다. 동기화란 하나의 자원을 여러 스레드가 이용할 동시에 자원을 이용하는 것이 아니라 하나의 스레드가 자원을 점유하고 있으면 다른 스레드들은 기다리는 원리입니다. 그래서, 차례대로 일처리가 되는 것입니다.

 

ICollection 인터페이스에서는 이러한 동기화를 위한 자원 관리의 효율을 위해서 SyncRoot라는 속성을 제공해 주고 있습니다. 다음과 같이 lock 키워드를 이용하시면 공유자원에 순서대로 접근하게 해줍니다.

 

lock(c.SyncRoot){

// 공유자원 c 이용하여 작업

}

 

동기화에 관련된 보다 자세한 사항을 알고자 한다면 Thread 부분을 참고하시기 바랍니다.
[본문링크] 컬렉션4 : ICollection 인터페이스
[1]
코멘트(이글의 트랙백 주소:/cafe/tb_receive.php?no=3055
작성자
비밀번호

 

SSISOCommunity

[이전]

Copyright byCopyright ⓒ2005, SSISO Community All Rights Reserved.