Synchronized로 검색한 결과 :: 시소커뮤니티[SSISO Community]
 
SSISO 카페 SSISO Source SSISO 구직 SSISO 쇼핑몰 SSISO 맛집
추천검색어 : JUnit   Log4j   ajax   spring   struts   struts-config.xml   Synchronized   책정보   Ajax 마스터하기   우측부분

회원가입 I 비밀번호 찾기


SSISO Community검색
SSISO Community메뉴
[카페목록보기]
[블로그등록하기]  
[블로그리스트]  
SSISO Community카페
블로그 카테고리
정치 경제
문화 칼럼
비디오게임 스포츠
핫이슈 TV
포토 온라인게임
PC게임 에뮬게임
라이프 사람들
유머 만화애니
방송 1
1 1
1 1
1 1
1 1
1

Synchronized로 검색한 결과
등록일:2008-03-03 10:35:01
작성자:
제목:Synchronized(동기화)




1.  Modifier(메소드)

run메소드를  동기화  시킨다.

  =>  public  Synchronized  void  run(){

              //내용

}

2.  코드  블럭

코드의  일부분에  동기화  시킨다.

  =>  Synchronized(this)  {

          //this  =>  현재  클래스의  멤버  변수들에  대한  동기화가  보장된다.

          //오브젝트(Object  o)가  와야한다.(프로그램에서  사용하고  있는  객체를  주면된다.)

          //내용

}                                          

  

LOCK  Flag  =  >  잠금  부분을  열수  있는  키와  같다.

LOCK  Pool  =  >  스래드가  락을  사용하고  있으면  이부분에서  기다린다.

  

스레드로  하여  코드와  변수를  공유하는  코드  한객체변수로  2개의  스래드를  생성하고  1~10까지의  숫자를  공유한다.  하나의  객체를  생성하고  그것을  두개의  스래드로  객체를  생성해도  스래드는  각각의  스택을  갖고  그  저장장소에  지역변수를  저장하므로  각자의  스래드의  실행결과를  확인  할  수  있을것이다.  하지만  문제가  되는것은  인스턴스  변수로  선언할때  이것은  HEAP영역에  저장되기에  코드와  변수를  함께  공유하게  되는것이다.  이것은  같은숫자가  두번  찍히는  이상한  결과를  가져오게  되는데  오늘은  이것의  문제점에  대해  알아보고    Synchronized에  대하여  알아보도록  하겠다.

class  ThreadEx1  implements  Runnable  {  
          int  i=1;
          public  void  run(){
                    for(;i<=10;i++){
                            System.out.println(i);
                            try{
                                    Thread.sleep(20);
                            }catch(InterruptedException  ie){
                                      ie.printStackTrace();
                            }
                  }
        }
}
class  MyThread1{    //메인은  항상  같으므로  처음에만  한번  만들겠다.
          public  static  void  main(String[]  args)  {
                    ThreadEx1  te  =  new  ThreadEx1();
                    Thread  t1  =  new  Thread(te);  

                    Thread  t2  =  new  Thread(te);

/*

Thread  t1  =  new  Thread(te,"A");  

Thread  t2  =  new  Thread(te,"B");    

      //Thread(ThreadGroup  group,  String  name)          
    //      Allocates  a  new  Thread  object.
    //te의  객체에  "A"와  "B"라는  이름을  갖는  스래드를  생성한다.

*/
                    t1.start();
                    t2.start();
          }
}

여  기에  Synchronized라는  키워드를  사용할  것인데    t1이라는  스래드가  실행되고  있을때,  t2라는  스래드가  동시에  실행되지  않도록하는  역할을  한다.  이것의  사용은  메소드와  코드내  블록으로  사용할수  있다.  우선  메소드에  선언하는것을  알아보도록  한다.  오버라이드  하는  run()메소드에서  해보면...public  Synchronized  void  run(){}  으로  선언한다.  아래예제의  결과를  보면...  t1스래드가  시작되어  run()메소드를  실행하는데  동기화  메소드이므로  t1스래드가  실행되면  t2스래드는  t1스래드가  끝날때까지  Lock  Pool이라는  곳에서  기다리게된다.  t1스래드가  끝나고  t2스래드가  시작되면  인스턴스변수의값이  10이  초과되었으므로  더이상  실행되지  않는것을  확인할  수  있을  것이다.  코드  블록내에  Synchronized  사용가능하다.  
  public  void  run(){
    Synchronized(this){
      for(;i<=10;i++){
        System.out.println(i);
          try{
            Thread.sleep(20);
          }catch(InterruptedException  ie){
            ie.printStackTrace();
          }
      }
    }
  }
이렇게  사용가능하며  코드블록  동기할때  Synchronized(  )  이  괄호사이에  Object값을  넣어줘야  한다.  그래서  this를  사용하였다.  여기서  this는  현재  클래스  멤버  변수들에  대한  동기화가  보장된다.
class  ThreadEx1  implements  Runnable  {  
          int  i=1;

          /*public  Synchronized  void  run(){
                    for(;i<=10;i++){
                            System.out.println(i);
                            try{
                                      Thread.sleep(20);
                            }catch(InterruptedException  ie){
                                        ie.printStackTrace();
                            }
                }
    }*/

          public  void  run(){
                    Synchronized(this){
                              for(;i<=10;i++){
                                      System.out.println(i);
                                      try{
                                                Thread.sleep(20);
                                      }catch(InterruptedException  ie){
                                                ie.printStackTrace();
                                      }
                              }
                    }

          }
}

이번에는  Thread생성자를  이용하여  현재스래드의  상태와  그  이름을  출력해보도록  하겠다.
Thread  생성자  api를  참고하고  메소드  summary중  currentThread()와  getName()를  참고한다.

class  ThreadEx1  implements  Runnable  {  
          int  i=1;

          public  void  run(){
                    Synchronized(this){
                            String  name  =  Thread.currentThread().getName();  

    //API문서를  참고하자!  ,현재  사용중인  스래드  객체의  참조를  반환한다().스래드의  이름을  리턴한다()

                              for(;i<=10;i++){
                                      System.out.println(i);
                                      try{
                                                Thread.sleep(20);
                                      }catch(InterruptedException  ie){
                                                ie.printStackTrace();
                                      }
                              }
                    }

          }
}
  
이번에는  스래드의  이름이  "A"이고  50보다  작으면  스래드를  쉬게하고(sleep)  50과  100사이에서는  "A"스래드와  "B"스래드가  같이  출력되는  프로그램을  만들어  보겠다.  여기서  주의할점은    synchronizer블록  내에서  sleep()를  사용하지  않아야  한다는  점이다.아래예제의  출력결과를  보면  [A는  50이  넘어도  찍히지  않는다.  B만계속  찍힌다.-else블록하면]  ||  [하지않으면  -  A와B가  순서없이  뒤죽박죽  출력된다.)  이것은  동기화  블록내에서  스래드를  sleep하게  하면  LOCK  Flag를  반환하지  않고  쉬게  되므로  A는  계속  잠들어있게되는  것이다.

  

  

class  ThreadEx1  implements  Runnable  {  
          int  i=1;

          public  void  run(){

                    while(i<=100){
                              Synchronized(this){
                                        String  name  =  Thread.currentThread().getName();  

//API문서를  참고하자!  ,현재  사용중인  스래드  객체의  참조를  반환한다().스래드의  이름을  리턴한다()
                                        if(name.equals("A")  )  {
                                                  if(i  <  50){
                                                            try{
                                                                    Thread.sleep(20);
                                                            }catch(InterruptedException  ie){
                                                                    ie.printStackTrace();
                                                            }
                                                  }
                                        }
                                        else{    //하지  않으면  뒤죽박죽  출력된다.
                                                  System.out.println(name+":"+i);
                                                  i++;
                                        }
                              }
                    }
          }
}
위  의  예제에서  문자점이었던  "A"스래드...  sleep()은  동기화  에서  사용하지  않고  wait()를  사용함으로써  해결할수  있다.  기다린다는  메소드  java.lang.Object의  api문서를  참고하자.  또  여기서  문제점은  기다리게  한다면  그것을  불러줘야  다시  사용할  수  있다는  점이다.  그래서  wait는  notify(),notifyAll()과  같이  사용되어야  한다.  아래의  예제를  보도록  하자.

  

class  ThreadEx1  implements  Runnable  {  
          int  i=1;

          public  void  run(){

                    while(i<=100){
                              Synchronized(this){
                                        String  name  =  Thread.currentThread().getName();  

//API문서를  참고하자!  ,현재  사용중인  스래드  객체의  참조를  반환한다().스래드의  이름을  리턴한다()
                                        if(name.equals("A")  )  {
                                                  if(i  <  50){
                                                            try{
                                                                    wait();
                                                            }catch(InterruptedException  ie){
                                                                    ie.printStackTrace();
                                                            }
                                                  }
                                        }
                                        else{    //하지  않으면  뒤죽박죽  출력된다.
                                                  System.out.println(name+":"+i);
                                                  i++;

                                                  if(i>50)
                                                  notify();
                                        }
                              }
                    }
          }
}

  

Synchronized

wait()

nofity()

notifyall()

Thread  life  cycle

  

동기화

스레드들이  공유하고  있는  자원에  대한  권한을  얻은  스레드만이  어떤  작업을  수행할  수  있도록

하는  것을  동기화(syncronzation)라고  한다.

  

동기화  블록

동기화  블록은  어떤  객체의  모니터(monitor)를  가지고  있는  스레드가  실행  권한을  획득하게  하는  방법이다.  모니터는  자바의  모든  객체가  가지고  있는  동기화  보호  객체로  객체에  대한  권한  정도라고  보면된다.

블록의  형식

Synchronized(someObject){

    [코드]

}

  

동기화  메소드

동기화  블록은  블록  안의  코드만을  동기화하는  반면에  동기화  메소드는  메소드  전체를

동기화한다.

메소드의  형식

Synchronized  void  f(){

    [코드]

}

  

동기화  메소드를  동기화  블록으로...

void  f(){

    Synchronized(this){

        [코드];

    }

}

  

쓰레드를  기다리게  하는  메소드로  wait()이  있고,  기다리고  있는  스레드에게  알리는  메소드로는  notify()가  있다.  그런데  특이한  점은  wait()과  notify()는  Thread  클래스의  멤버가  아니고  Object  클래스의  멤버라는  것이다.  사실  기다리거나  알리는  것도  객체의  모니터를  이용하는  것이기  때문이다.

  

wait()을  호출하는  코드  조각이다.

Synchronized(key){                                      //  x1

    ...

    try{

        if(조건)key.wait();                                  //  x2

    }catch(InterruptedException  ie){}

    ...

}

  

notify()는  대기  중인  스레드에게  알려서  깨우는  기능을  한다.  다음의  notify()를  호출하는  코드  조각이다

  

Synchronized(key){            //  x1

    ...

    key.notify();                      //  x2

    ...

}

  

notifyall()은  다수의  스래드가  실행중일때  모든  스래드를  깨워서  알리는  기능을  하는데

문제점을  발견할수  있을것이다.  이것은  코드를  하나더  작성하여  비교해준뒤

실행하면  문제를  해결할수  있다...

출처  Synchronized(동기화)|작성자  에스케이