메뉴 건너뛰기

조회 수 104 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

  기본적인 쓰레드 사용


Thread를 상속받아 run() 메소드를 오버라이딩을 함으로써 간단한 Thread을 구현 해보겠습니다.

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Thread1 extends Thread{
    int index ;
    public Thread1(int index)
    {
        this.index = index;
    }
    public void run()                            //실제로 Thread가 동작하는 내용을 구현합니다.
    {
        System.out.println(index + "번째 Thread Start");
        try
        {
            Thread.sleep(2000);         //단순히 2초동안 thread가 생성되었따가 종료됩니다.
        }catch(Exception e){}
        System.out.println(index + "번째 Thread End");
    }
}
public class Main {
    
    public static void main(String argsp[])
    {    
        Thread1 thread1 = new Thread1(1); //위에 구현한 클래스 객체 생성
        Thread1 thread2 = new Thread1(2);
        Thread1 thread3 = new Thread1(3);
        
        thread1.start();                           //start() 메서드를 통해 Thread 시작, run() 호출됨
        thread2.start();
        thread3.start();
    }
}
 

 

쓰레드 동작을 위해 Thread를 상속받는 Thread1 클래스를 구현합니다. thead의 인덱스를 넘겨받는 생성자와 쓰레드의 동작을 구현하는 run() 메서드를 오버라이딩 합니다.

Main 영역에서 Thread1 클래스의 객체를 생성하고 start() 메서드를 호출함으로써 쓰레드를 동작시킵니다.

 

 

■ join()을 통한 쓰레드 구현


위에 예제 실행 결과를 보면 첫 번째 쓰레드가 먼저 시작했음에도 불구하고 3번째 thread가 먼저 끝났다는 메세지가 먼저 뜹니다. 이것은 thread1 쓰레드를 실행하다가 실행흐름이 thread3로 옮겨지게 되면서 이런 경우가 발생합니다. 하지만 첫 번째 쓰레드가 끝나야지 2번쨰 쓰레드가 실행되고 2번째 쓰레드가 끝나야지 3번째 쓰레드를 실행시키고 싶을 경우가 있을 수 있습니다. 그럴때 사용하는데 join() 입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class Thread1 extends Thread{
    int index ;
    public Thread1(int index)
    {
        this.index = index;
    }
    public void run()
    {
        System.out.println(index + "번째 Thread Start");
        try
        {
            Thread.sleep(2000);
        }catch(Exception e){}
        System.out.println(index + "번째 Thread End");
    }
}
    
public class Main {
    
    public static void main(String argsp[]) throws InterruptedException
    {    
        Thread1 thread1 = new Thread1(1);
        Thread1 thread2 = new Thread1(2);
        Thread1 thread3 = new Thread1(3);
        
        thread1.start();
        thread1.join();     //thread1이 종료될때 까지 기다립니다.
        thread2.start();
        thread2.join();    //thread2가 종료될때까지 기다립니다.
        thread3.start();
    }
}
 

 

start() 호출 후에 join() 메서드를 호출하는 구조입니다. join은 해당 쓰레드가 종료 될 때까지 대기상태에 있도록 해줍니다.

 

 

■ Runnable 인터페이스


Thread 클래스를 상속받아 thread를 구현하는 방법도 있지만 Runnable 인터페이스를 구현하도록 하는 방법도 있습니다. 위에 예제를 Runnable 인터페이스를 구현하는 방법으로 수정 해보겠습니다.

  

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Thread1 implements Runnable{
    int index ;
    public Thread1(int index)
    {
        this.index = index;
    }
    public void run()
    {
        System.out.println(index + "번째 Thread Start");
        try
        {
            Thread.sleep(2000);
        }catch(Exception e){}
        System.out.println(index + "번째 Thread End");
    }
}
public class Main {
    
    public static void main(String argsp[]) throws InterruptedException
    {    
        Thread thread1 = new Thread(new Thread1(1));
        Thread thread2 = new Thread(new Thread1(2));
        Thread thread3 = new Thread(new Thread1(3));
        
        thread1.start();
        thread2.start();
        thread3.start();
        
    }
}

Thread 상속받는 대신 Runnable 인터페이스를 구현함으로써 thread를 사용하는 방식입니다.

Main에서 Thread 생성 정보로 구현한 클래스의 객체를 넘겨줌으로써 객체를 생성하는 방식입니다.

 

■ Synchronized 키워드를 활용한 동기화


동기화란 여러 개의 쓰레드가 한 개의 자원을 사용하고자 할 때 해당 쓰레드를 제외한 나머지 쓰레드는 접근을 못하도록 막는 것을 의미합니다.

 

예제는 각 쓰레드가 공통 자원을 사용하는데 있어서 순차적으로 한번씩 사용해야 하는 자원에 대해 접근한다고 가정을 하였습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Main {
    
    public static void main(String argsp[]) throws InterruptedException
    {    
        Resource resource = new Resource();
        Thread thread1 = new Thread(new Thread1(resource,"1번쓰레드"));
        Thread thread2 = new Thread(new Thread1(resource,"2번쓰레드"));
        Thread thread3 = new Thread(new Thread1(resource,"3번쓰레드"));
        
        thread1.start(); //차례대로 쓰레드를 실행
        thread2.start();
        thread3.start();
    }
}
 
public class Thread1 implements Runnable{
    private Resource resource;
    private String name;
    public Thread1(Resource resource,String name)
    {
        this.resource = resource;
        this.name = name;
    }
    public void run()
    {
        try
        {
            for(int i=0;i<3;i++)
            {
                resource.getResource(name); //0번 index부터 차례대로 자원을 사용
            }
        }catch(Exception e){}
 
    }
}
 
public class Resource {
    private int Resource_index = 0;
    public void getResource(String name)
    {
        System.out.println(name +"=" +Resource_index + "번째 resource 사용"); //자원을 사용했다고 가정
        Resource_index ++;                                                //다음 자원의 index
    }
}

 

프로그램은 thread1,thread2,thread3가 Resoucr 객체의 Resource_index를 0번부터 차례대로 호출해서 사용할려고 합니다. 한번 사용하고나면 Resource_index를 증가시키게 됩니다. 동기화 되지 않은 상태이며 결과를 먼저 보겠습니다.

 

 

0번째 자원은 여러번 사용 되었을 뿐만 아니라 순차적으로 자원을 사용하지도 못하고 있습니다.

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Main {
    
    public static void main(String argsp[]) throws InterruptedException
    {    
        Resource resource = new Resource();
        Thread thread1 = new Thread(new Thread1(resource,"1번쓰레드"));
        Thread thread2 = new Thread(new Thread1(resource,"2번쓰레드"));
        Thread thread3 = new Thread(new Thread1(resource,"3번쓰레드"));
        
        thread1.start(); //차례대로 쓰레드를 실행
        thread2.start();
        thread3.start();
    }
}
 
public class Thread1 implements Runnable{
    private Resource resource;
    private String name;
    public Thread1(Resource resource,String name)
    {
        this.resource = resource;
        this.name = name;
    }
    public void run()
    {
        try
        {
            for(int i=0;i<3;i++)
            {
                resource.getResource(name); //0번 index부터 차례대로 자원을 사용
            }
        }catch(Exception e){}
 
    }
}
 
public class Resource {
    private int Resource_index = 0;
    public synchronized void getResource(String name) //동기화
    {
        System.out.println(name +"=" +Resource_index + "번째 resource 사용");
        Resource_index ++;
    }
}

 

이번엔 synchronized 키워드를 사용하여 getResource()를 동기화 하였습니다.

 

 

 

이번에는 한번 사용된 자원은 재사용되지 않았고 순차적으로 잘 사용하고 있습니다.


List of Articles
번호 제목 날짜 조회 수
131 Eclipse에서 import문 자동으로 작성하는 기능 file 2016.09.19 4811
130 간단한 개인홈페이지 만들어보기 file 2016.08.29 4751
129 이클립스 플러그인 삭제방법 file 2016.09.19 4721
128 한글이 깨졌다! 인코딩(encoding)을 설정하자 file 2016.09.19 4715
127 GET 파라메타 쿼리문자열 컨트롤 : getQueryString 2016.12.09 4705
126 기존 프로젝트, Table, View 모두 다 삭제하기 file 2016.08.29 4608
125 예외처리(Exception handling)방법 file 2016.09.21 4585
124 No bean name '***Service' is defined 오류나는 이유 및 해결방법 file 2016.08.29 4561
123 자바용 날짜 계산 2016.09.19 4543
122 회원가입 양식에서 (필수/옵션)필드 추가/제거하기 file 2016.08.29 4471
121 [자바(스프링&mybatis&jsp) 프로젝트 & 아파치 &톰켓 연동 ] 이클립스 프로젝트 생성 순서08.commons-logging 설치 file 2016.08.18 4458
120 이클립스를 화려하게 꾸며보자 file 2016.09.19 4457
119 자바 JXL 엑셀파일을 읽어 배열리턴 : JAVA EXCEL ArrayList 2016.12.09 4389
118 My-SQL 을 이용한 JDBC file 2016.09.21 4282
117 배치관리 컴포넌트 생성 후 에러 날 때 해결방법 file 2016.08.29 4267
116 전자정부 표준프레임워크 설치하기 file 2016.08.29 4250
115 [자바(스프링&mybatis&jsp) 프로젝트 & 아파치 &톰켓 연동 ] 이클립스 프로젝트 생성 순서04.jdbc 드라이버 설치 file 2016.08.18 4209
114 자바 다양한 형변환. 그리고 아스키 코드 String char int : JAVA 2016.12.09 4188
113 eclipse 콘솔(로그)에 디버그(Debug) 모드에서 실행된 쿼리문을 보여주자. - 전자정부프레임워크 오라클 file 2016.08.29 4172
112 프로젝트 & 아파치 &톰켓 연동 ]2. 자바 설치 file 2016.08.18 4170
Board Pagination Prev 1 2 3 4 5 6 7 8 Next
/ 8

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved