728x90
반응형

동기화 (synchronization)

 - 멀티스레드 프로그램이 실행될 때, 다수의 스레드가 공유 데이터를 동시에 접근하는 경우가 발생한다.

 - 특히 다수의 스레드가 동시에 공유 데이터의 값을 변경시키는 경우에는 공유 데이터의 값이 정상적으로 변경되지 않는다.

 - 이것은 마치 여러 사람이 볼 일을 보려고 한 칸의 화장실에 동시에 들어가는 경우와 같다.
 - 공유 데이터를 동시 접근하는 여러 스레드에 의해 공유 데이터의 값이 비정상적으로 유지되지 않도록 스레드의 실행을 제어하는 기술을 스레드 동기화(thread synchronization)라고 부른다.

 - 스레드를 동기화하는 방법

 방법 1 : synchronized로 동기화 블럭 지정

 방법 2 : wait()-notify() 메서드로 스레드 실행순서를 제어

 

 

synchronized로 동기화 블럭 지정

 - 동기화된 메소드를 만들기 위해서는 synchronized키워드를 메소드 선언에 붙이면 된다.

 - synchronized 키워드가 붙어 있으면 하나의 스레드가 공유 메소드를 실행하는 동안에 다른 스레드는 공유 메소드를 실행할 수 없다.

     Class Counter {

             private int value=0;

             public synchronized void increment() { value++; }       //공유 데이터를 조작하는 메소드 앞에 synchronized를 붙인다.

             public synchronized void deccrement() { value--; }

             public synchronized void printCounter() { System.out.println(value); }

      }

 

 

synchronized로 동기화 블럭 지정

 - synchronized를 사용하면 하나의 스레드가 진입하면 스레드 작업이 끝날때까지 다른 스레드는 진입할 수 없다.

>>동기화_방법1

 

 

 

 

wait()-notify() 메서드로 스레드 실행순서를 제어

 - Object 클래스의 메서드로서 synchronized에서만 사용 가능하다.

 - synchronized 키워드를 이용해 공유된 객체의 자원을 하나의 스레드에서만 사용할 수 있게 락(lock)상태를 만들면 다른 스레드에서도 사용할 수 있게 만들기 위해 스레드간의 통신이 필요하다.

 - 이 때 자원을 점유하고 있던 동기화된 스레드가 wait() 메서드를 호출하면 락 상태의 자원을 더이상 사용하지 않고 대기 상태에 들어가고, notity메서드를 호출하면 다른 스레드에게 락 상태에 자원이 사용 가능함을 알리게 하여 다른 스레드들을 대기상태에서 자원을 사용 할 수있는 준비상태로 깨우게 된다.

 

>>동기화_방법2

728x90
반응형
728x90
반응형

스레드(thread)

 - 멀티 태스킹(muli-tasking) : 여러 개의 애플리케이션을 동시에 실행하여서 컴퓨터 시스템의 성능을 높이기 위한 기법

 - 다중 스레딩 : 하나의 프로그램이 동시에 여러 가지 작업을 할 수 있도록 하는 것

 - 각각의 작업은 스레드 라고 한다.

 

 

 

프로세스와 스레드

 프로세스(process) : 자신만의 데이터를 가진다.

 스레드(thread) : 동일한 데이터를 공유한다.

 

 

 

프로그램과 프로세스

  프로그램 ---(실행)---> 프로세스

 

▶프로그램:실행 가능한 파일(HDD)                        ▶프로세스:실행 중인 프로그램(메모리)

 

 

프로세스와 스레드

 프로세스 : 실행 중인 프로그램. 자원(resources)과 스레드(thread)로 구성

 스레드(thread) : 프로세스 내에서 실제 작업을 수행하는 것, 모든 프로세스는 하나 이상의 스레드를 가지고 있다.

           프로세스 : 스레드 = 공장 : 일꾼            

 

 

멀티프로세스와 멀티스레드

 " 하나의 새로운 프로세스를 생성하는 것보다 하나의 새로운 스레드를 생성하는 것이 더 적은 비용이 든다." 

 

 

 

멀티스레드의 장단점

 장점

- CPU의 사용률을 향상시킨다.

- 자원을 보다 효율적으로 사용할 수 있다.

- 사용자에 대한 응답성(responseness)이 향상된다.

- 작업이 분리되어 코드가 간결해 진다.

 

 단점

- 동기화(synchronization)에 주의해야 한다.

- 교착상태(dead-lock)가 발생하지 않도록 주의해야 한다.

- 각 쓰레드가 효율적으로 고르게 실행될 수 있게 해야 한다.

- 프로그래밍할 때 고려해야 할 사항들이 많다.

※교착상태(dead-lock) : 두 스레드가 자원을 점유한 상태에서 서로 상대편이 점유한 자원을 사용하려고 기다리느라 진행이 멈춰있는 상태

 

 

 

스레드를 사용해야 하는 이유

- 웹 브라우저에서 웹 페이지를 보면서 동시에 파일을 다운로드할 수 있도록 한다.

- 워드 프로세서에서 문서를 편집하면서 동시에 인쇄한다.

- 게임 프로그램에서는 응답성을 높이기 위하여 많은 스레드를 사용한다.

- GUI에서는 마우스와 키보드 입력을 다른 스레드를 생성하여 처리한다.

 

 

스레드 생성과 실행

 스레드는 Thread 클래스가 담당한다. (java.lang.Thread)

        Thread t= new Thread();       //스레드 객체를 생성한다.

         t.start();                              //스레드를 시작한다.       

 스레드의 작업은 Thread 클래스의 run() 메서드 안에 기술한다.

 

 

 

스레드를 사용하는 방법

  스레드 생성 방법

    Thread 클래스를 상속하는 방법 :Thread 클래스를 상속받은 후에run() 메서드를 오버라이딩한다.Thread 클래스를 상속 받으면 다른 클래스는 상속받을수 없다.

    Runnable 인터페이스를 구현하는 방법 : run() 메서드를 가지고 있는 클래스를 작성하고, 이 클래스의 객체를 Thread 클래스의 생성자를 호출할 때 전달한다.

 

1. Thread클래스를 상속

  class MyThread extends Thread {

         public void run () { /* 작업내용 */ } //Thread클래스의 run()을 오버라이딩

   }

 

2. Runnable인터페이스를 구현

  class MyThread implements Runnable {

         public void run () { /* 작업내용 */ }  // Runnable인터페이스의 추상메서드 run()을 구현

   }

 

 

 

Thread 클래스 상속하는 방법

 - Thread를 상속받아서 클래스를 작성한다. (java.lang.Thread)

 - run() 메서드를 오버라이딩한다.

     class My Thread extends Thread {

          public void run()  {

                ...    // 수행해야하는 작업을 적어준다.

           }

      }

- Thread 객체를 생성한다.

        Thread t = new MyThread ();

- start()를 호출하여서 스레드를 시작한다.

         t.start();

 

 

>>Thread 클래스 상속하는 방법

 

 

 

 

Runnable 인터페이스를 구현하는 방법

 - Runnable 인터페이스를 구현한 클래스를 작성한다. (java.lang.Runnable)

 - run() 메서드를 오버라이딩 한다.

        class MyRunnable implements Runnable {

                public void run() {

                      ...

                 }

        }

 - Thread 객체를 생성하고 이때 MyRunnable 객체를 인수로 전달한다.

        Thread t = new Thread(new MyRunnable ());

 - start()를 호출하여 스레드를 시작한다.

        t.start();

 

 

 

>>Runnable 인터페이스를 구현하는 방법

 

 

 

 

 

 

Thread 클래스의 메서드

 

 

 

 

 

>>싱글 스레드

하나의 스레드로 사용자의 입력을 받는 작업과 하면에 숫자를 출력하는 작업을 처리하기 때문에 사용자가 입력을 종료하기 전까지는 화면에 숫자가 출력되지 않고, 입력을 마치면 화면에 숫자가 출력된다.(※ 사용자가 입력을 종료하기 전까지는 아무 일도 못하고 기다려야 한다.)

 

 

 

 

 

 

>>멀티 스레드

두 개의 스레드로 사용자의 입력을 받는 작업과 화면에 숫자를 출력하는 작업을 처리하기 때문에 사용자의 입력을 기다리는 동안 다른 스레드가 작업을 처리할 수 있다. 입력받는 부분과 출력하는 부분을 두 개의 스레드로 나누어 처리하기 때문에 사용자가 입력을 종료하지 않아도 화면에 숫자가 출력된다.

 

 

 

 

 

>>main 스레드

 

 

​>>sleep() 메서드

​sleep()은 CPU의 시간을 다른 스레드에게 넘겨주는 방법이다. 다른 스레드와 보조를 맞추는 역할도 한다.

 

​join() 메서드

- 하나의 스레드가 다른 스레드의 종료를 기다리게 하는 메서드이다.

- 예를 들어서 t가 현재 실행 중인 스레드 객체이면 다음 문장을 t가 종료될 때까지 기다린다.

>>join() 메서드

join()을 사용하지 않으면 main()이 바로 종료되지만, join()을 사용해서 th1과 th2의 작업을 마칠때까지 main()이 기다리도록 한다.

한 쓰레드의 작업 중간에 다른 쓰레드의 작업이 필요할 때 join()을 사용한다.

 

 

>>join() 메서드

두 스레드가 번갈아가며 실행되지 않고, 순차적으로 실행되는 경우 (th1 실행 후 th2 실행)

 

728x90
반응형
728x90
반응형

다형성(polymorphism)

- 객체들의 타입이 다르면 똑같은 메시지가 전될되더라도 서로 다른 동작을 하는 것

- 강아지의 speak()메서드에서는 "멍멍"이라고 동작하고, 고양이의 speak()메서드에서는 "야옹"이라고 동작하도록 구현하는 것


상향 형번환(UP-Casting)

- 부모타입의 참조변수로 자식타입의 객체를 다룰 수 있는 것

- 서로 상속관계에 있는 타입간의 형변환만 가능하다.

- 자식 타입에서 부모타입으로 형변환하는 경우에는 형변환 생략가능하다.


상향 형변환이 가능한 이유

- 자식클래스 객체는 부모클래스 객체를 포함하고 있기 때문이다.



<형변환 사용하는 이유>



<형변환 사용한 경우>






객체의 타입을 알아내는 방법

  Shape s=getShape();     //참조변수 s가 가리키는 객체의 실제 타입은? Shape일수도 있지만 Rectangle일수도 있고 Circle일수도 있다.

   if ( s instanceof Rectangle ) {

        System.out.println("Rectangle이 생성되었습니다.");

   }

  else {

        System.out.println("Rectangle이 아닌 다른 객체가 생성되었습니다.");

  }





다형성의 이용

  메서드의 매개변수로 부모클래스의 참조변수를 이용한다.

  -> 다형성을 이용하는 전형적인 방법

 




제어자 조합할 때 주의사항

메서드에 static과 abstract를 함께 사용할 수 없다.

-> static메서드는 몸통(구현부)이 있는 메서드에만 사용할 수 있기 때문이다.

클래스에 abstract와 final을 동시에 사용할 수 없다.

-> 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문이다.

abstract메서드의 접근제어자가 private일 수 없다.

-> abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손 클래스에서 접근할 수 없기 때문이다.

메서드에 private와 final을 같이 사용할 필요는 없다.

-> 접근 제어자가 final인 메서드는 오버라이딩될 수 없기 때문이다.

728x90
반응형
728x90
반응형
추상 클래스
추상적인 개념을 표현하고, 완성되지 않은 메서드를 가지고 있는 클래스
- 메서드가 미완성되어 있기 때문에 추상 클래스로는 개체를 생성할 수 없다.
- 추상 클래스는 주로 상속관계에서 추상적인 개념을 나타내기 위한 목적으로 사용되고, 단일 상속이 가능하다.
- 추상 메서드를 하나라도 가지고 있으면 추상 클래스가 된다.
- 추상 메서드 : 동작 방식을 결정할 수 없을 때, 확정할 수 없는 경우, 동작부분을 기술하지 않고 비워두는 메서드
- 메서드 오버라이딩이 빈번하게 사용될 것이 예측될 경우에도 사용한다.
- 예) 동물(animal) 클래스를 구형하려고 할 때 동물에 대한 개념은 알고 있지만 구체적으로 어떤 동작을 하는지 알 수 없기 때문에 구체적인 동작을 구현하기 어렵다. move()라는 메서드를 정의할 경우, 동물이 움직인다는 것은 알지만 구체적으로 날아다니는지 기어다니는지는 알 수 없다. 이런 경우에 animal은 추상 클래스로 구현한다.
- 추상 클래스의 예) 동물, 포유류, 어류, 조류, 도형 등
- 추상 메서드의 대표적인 예) 쓰레드의 run() 메서드

public abstract class Animal {      //추상클래스 : 추상메서드를 가지고 있는 클래스
      public abstract void move();   // ';'으로 종료됨을 유의! , 추상메서드 정의
      ...
 };





인터페이스(Interface)
- 인터페이스는 클래스가 아니다. interface 키워드로 선언한다.
- 인터페이스는 객체와 객체 사이의 상호 작용을 나타낸다.
다중 상속의 기능을 구현하려고 할 때, 인터페이스를 사용한다.
- 인터페이스는 추상 메서드만 가질 수 있고, 일반 메서드는 가질 수 없다.
- 인터페이스는 static final형태의 상수만 가질 수 있다. 변수는 가질 수 없다.
- 인터페이스는 데이터는 표현할 수 없고 메서드(함수)만 표현이 가능하다.
- 이미 클래스 상속을 받고 있더라도 인터페이스의 상속을 받는 것이 가능하다.
- 인터페이스도 추상클래스처럼 객체를 생성할 수 없다. 다른 클래스에 의해서 구현(implements) 하여 사용한다.
- 추상 메서드는 자식 클래스에서 반드시 구현해야 한다.

<인터페이스와 추상클래스의 구분>
 - 인터페이스 : 모든 메서드가 추상메서드이면 인터페이스로 구현, 다중 상속
 - 추상클래스 : 여러개의 메서드 중 일부가 추상메서드이면 추상클래스로 구현, 단일 상속

<인터페이스의 사용>
 - 인터페이스의 선언 : interface 인터페이스이름
 - 인터페이스의 구현 : class 클래스이름 implements 인터페이스이름
 
   public interface 인터페이스_이름 {
        반환형 추상 메서드1(...) ;
        반환형 추상 메서드2(...) ;       //인터페이스 안에는 추상 메서드들이 정의된다.
         ...
   }
                                                                                                                                             
  public class 클래스_이름 implements 인터페이스_이름 {
        반환형 추상 메서드1(...) {
         ...
        }
        반환형 추상 메서드2(...) {
         ...
        }                               //인터페이스를 구현하는 클래스는 추상 메서드의 몸체를 구현하여야한다.
   }



<여러 인터페이스를 동시에 구현>



인터페이스와 다중 상속
- 만약, 클래스에서 다중상속이 허용된다면 객체를 생성하여 인스턴스 변수에 접근할 때 obj.x는 SuperA 클래스의 멤버인지 SuperB 클래스의 멤버인지 구분이 안된다. 그래서 자바에서 클래스는 단일 상속만 허용한다.
- 다중상속의 효과를 구현하고 싶다면, 인터페이스를 구현하면서 동시에 다중 상속을 하면된다.




<상수 정의>
  인터페이스에서는 변수는 사용할 수 없고, 상수만 사용할 수 있다.


728x90
반응형
728x90
반응형

상속

 상속의 장점

 - 상속을 통하여 기존 클래스의 필드와 메소드를 재사용

 - 기존 클래스의 일부 변경도 가능

 - 상속을 이용하게 되면 복잡한 GUI프로그램을 순식간에 작성

 - 상속은 이미 작성된 검증된 소프트웨어를 재사용

 - 신뢰성 있는 소프트웨어를 손쉽게 개발, 유지 보수

 - 코드의 중복을 줄일 수 있다.

 

  class SubClass extends SuerClass (extends:상속을 의미한다. 수퍼클래스를 확장하여 서브 클래스를 작성한다는 의미) (SuperClass: 부모클래스)

 {

        ... //추가된 메소드와 필드

  }

 

상속의 정의

 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것

 두 클래스를 부모와 자식으로 관계를 맺어주는 것

 자식은 부모의 모든 멤버를 상속받는다.

 자식의 멤버개수는 부모보다 작을 수 없다. (같거나 많아야 한다.)

 

클래스간의 관계 - 상속관계

 공통 부분은 부모 클래스에서 관리하고, 개별 부분은 자식 클래스에서 관리한다.

 부모의 변경은 자식에게 영향을 미치지만, 자식의 변경은 부모에게 영향을 주지 않는다.

 

 

단일상속

 java는 단일상속만을 허용한다. 하지만 인터페이스를 사용하여 다중상속의 효과를 낼 수 있다. ( C++은 다중상속 허용 )

    class TVCR extend TV,VCR {

       ...

    }   //이와 같은 표현은 허용하지 않는다.

 

 비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 한다.

<상속과 포함>

 

 

상속에서 접근 지정자

 private (X)

 protected (O)

 package (O)

 public (O)

 

<접근 지정자>

 

 

 

 

메서드 재정의 (오버라이딩)

 메서드 재정의 : 자식 클래스가 필요에 따라 상속된 부모의 메서드를 변경하여 사용하는 것

 주의할점 :

 - 메서드의 헤더(머리부분)은 그대로 두고, 바디(몸체부분)만 교체하는 것이다.

 - 메서드의 헤더 부분은 부모 클래스의 헤더와 동일해야 한다. (메서드 이름, 반환타입, 매개변수의 개수와 데이터타입이 일치해야 한다.)

 - 메서드가 public으로 선언되어 있는 경우에만 재정의가 가능하다. private메서드는 오버라이딩할 수 없다.

 - 부모 클래스의 메서드보다 더 좁은 범위의 접근제어자로 변경할 수 없다.

   예를 들어, 부모 클래스의 메서드가 protected로 선언되어 있는 경우에 자식클래스의 재정의 메서드는 protected나 public으로만 선언 가능하다.

 

<메서드오버라이딩>

 

 

 

재정의 (오버라이딩)와 중복정의 (오버로딩)의 차이점

 메서드 오버라이딩(재정의) : 부모클래스를 상속받은 자식클래스에서 부모의 메서드를 변경하여 사용하는 것

 메서드 오버로딩(중복정의) : 같은 클래스 안에서 이미 정의된 메서드를 변경하여 사용하는 것

 

<오버로딩>

 

 

 

super 키워드

 - 상속관계에서 부모 클래스의 변수나 메서드를 참조하기 위해 사용되는 키워드

 - super를 사용하여 부모클래스의 변수나 메서드를 호출할 수 있다.

 - 메서드를 재정의할 때, 부모클래스의 메서드를 완전히 다른 것으로 바꾸는 경우보다 내용의 추가하는 경우가 많다.

   이런 경우에 super 키워드를 사용하여 부모 클래스의 메서드를 호출한 뒤 필요한 부분을 추가하여 사용하면 된다.\

 

 

 

<super생성자>

 

 

 

Object클래스

 - 부모클래스를 정의하지 않으면 자동으로 Object클래스가 부모클래스가 된다.

 - 모든 클래스는 Object 클래스에 정의된 11개의 메서드를 상속받을 수 있다.

 - Object 클래스는 java.lang 패키지에 들어 있으며 자바 클래스 계층 구조에서 맨 위에 위치하는 최고의 조상 클래스

 

Object의 메서드

 protected Object clone()

 -> 객체 자신의 복사본을 생성하여 반환한다.

 public boolean equals(Object obj)

 -> obj가 이 객체와 같은지를 나타낸다.

 protected void finalize()

 -> 가비지 콜렉터에 의하여 호출된다.

 public final Class getClass()

 -> 객체를 생성한 클래스 정보를 반환한다.

 public int hashCood()

 ->객체에 대한 해쉬 코드를 반환한다.

 public String toString()

 -> 객체의 문자열 표현을 반환한다.

 

 

getClass()메서드

 - 객체가 어떤 클래스로 생성되었는지에 대한 정보를 반환하는 메서드

>> getClass

 

 

 

equals()메서드

 - 두개의 객체를 비교하여 같으면 ture를 반환하는 메서드

 - equals() 메서드는 재정의(오버라이딩)하여 사용해야 한다.

>>equals

 

 

 

toString()메서드

 - Object 클래스의 toString() 메서드는 객체가 가지는 값을 문자열 형태로 반환하는 메서드, 객체가 생성되면 자동 호출된다. 오버라이딩하여 사용한다.

>>tostring

 

 

 

final 클래스와 final 메서드

 - 클래스에 final 키워드를 붙이면 상속할 수 없는 클래스

 - 메서드에 final 키워드를 붙이면 오버라이딩할 수 없는 메서드

>>Final

728x90
반응형

+ Recent posts