달력

12

« 2024/12 »

  • 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

음 이런 내용에 대해 꼭 알아야해! 완전 중요해! 필수야! 이런건아니지만.. 

알아서 나쁠거없고 다 차곡 차곡 쌓이는 지식이기 때문에 ㅎㅎㅎㅎ ! 


정리를 해본다.. 


쓰레드 그룹은 말그대로 thread group이다 ㅋㅋ 

서롸 관련된 쓰레드를 그룹으로 다루기 위한걸로 폴더를 생성해서 관련된 파일들을 함께 넣어서 

관리하는 것처럼 쓰레드 그룹을 생성해서 쓰레드를 그룹으로 묶어서 관리할 수 있다. 

폴더 안에 폴더를 넣는거마냥 

쓰레드 그룹에 다른 쓰레드 그룹을 포함시킬수도 있는데 


쓰레드 그룹은 보안상의 이유로 도입된 개념이라고 한다.(자세한건 더 찾아봐야할듯)

자신이 속한 쓰레드 그룹이나 하위 쓰레드 그룹은 변경할 수 있지만 

다른 쓰레드 그룹의 쓰레드를 변경할수는 없는부분?!


자바에서 ThreadGroup을 사용해서 생성할 수 있고, 주요 생성자와 메서드를 제공한다. 

쓰레드는 반드시 쓰레드 그룹에 포함되있어야하기때문에


쓰레드 그룹을 지정하는 생성자를 사용하지 않은 쓰레드는 기본적으로 

자신을 생성한 쓰레드와 같은 그룹에 속한다. 


자바 어플리케이션이 실행되면 JVM은 main과 system이라는 쓰레드 그룹을 만들고 JVM운영에 필요한 쓰레드를 생성!

그리고 그 쓰레드 그룹에 포함시킨다. 


ex) main메서드를 수행하는 main이라는 이름의 쓰레드는 main쓰레드 그룹에 속하고, 

가비지 컬렉션을 수행하는 Finalizer쓰레드는 system쓰레드 그룹에 속한다. 


우리가 생성하는 모든 쓰레드 그룹은 main쓰레드 그룹의 하위 쓰레드 그룹이 되며, 

쓰레드 그룹을 지정하지 않고 생성한 쓰레드는 자동적으로 main쓰레드 그룹에 속하게된다. 



음 내가 이걸 정리하면서 느끼는건 아.. 이런게 있구나 !_! 

쓰레드그룹이라는게 있고 이렇게 사용하는구나..! 

나중에 정리해야할 일이 있으면 그때 더 자세히.. 


<데몬스레드(daemon thread)와 일반 스레드(non-daemon thread)>


자바에서 스레드는 두가지 종류로 구분된다.


첫째는 데몬 스레드(daemon thread)인데 JVM이 스스로 필요에 의해 사용하는 스레드이다. 

데몬쓰레드는 다른 일반 쓰레드의 작업을 돕는 보조적인 역학을 하는 쓰레드라서 

일반 쓰레드가 모두 종료되면 데몬 쓰레드는 강제적으로 자동 종료된다. 

-->데몬 쓰레드는 일반 쓰레드의 보조역할을 수행하기때문에  일반스레드가 종료되고나면 

    데몬쓰레드의 존재의 의미가 없기 때문이다. 

(JVM은 응용프로그램에서 생성한 일반 스레드가 하나라도 살아 있는 한 실행을 계속 한다.)

이 점을 제외하고는 일반쓰레드와는 다르지 않다. 


ex))가비지컬렉터, 워드프로세서 자동저장, 화면 자동갱신 등이있다.. 

가비지 걸렉터가 대표적인 데몬스레드인데 응용프로그램에서 작성한 스레드를 데몬스레드로 표시해서 

JVM이 데몬스레드로 인식하게 할 수도있다.


데몬 쓰레드는 무한루프와 조건문을 이용해서 실행 후 대기하고 있다가 특정 조건이 만족되면 

작업을 수행하고 다시 대기하도록 작성한다.

--

데몬쓰레드는 일반스레드의 작성방법과 실행방법이 같다.

 다만 

쓰레드를 생성한 다음 실행하기 전에  setDaemon(true)를 호출하기만 하면 된다. 

(데몬스레드가 생성한 쓰레드는 자동적으로 데몬쓰레드가 된다! )

 


일반쓰레드 (non-daemon thread)는 응용프로그램에서 생성한 스레드이다. 

main( )메소드도 대표적인 일반쓰레드다. 


:
Posted by Gongdile

쓰레든느 우선순위(priority)라는 속성(멤버변수)를 가지고 있다. 

이 우선순위의 값에 따라 쓰레드가 얻는 실행시간이 달라진다. 


쓰레드가 수행하는 작업의 중요도에 따라 쓰레드의 우선순위를 서로 다르게 지정하여 특정 쓰레드가 더 많은 작업시간을 갖도록 할 수 있다. 


예를들어서 내가 카카오톡을 하는데 파인을 다운로드 처리하는 쓰레드보다 채팅 내용 전송하는 쓰레드 우선순위가 더 높아야

채팅하는게 불편함이 없을거다.

카카오톡 하는데 사진다운 받는동안은 채팅을 못한다던가.. 기다려야한다던가 이러면 엄청 불편할것이다. 


이렇게 시각적인 부분이나 사용자에게 빠르게 반응해야하는 작업을 하는 쓰레드의 우선순위는 다른 작업을 수행하는 쓰레드에 비해 높아야 한다.



<쓰레드의 우선순위 지정하기>


쓰레드의 우선순위와 관련된 메서드와 상수는 다음과 같다. 


void setPriority (int newPriority)  쓰레드의 우선순위를 지정한 값으로 변경한다.
int getPriority()                         쓰레드의 우선순위를 반환한다.
 
public static final int MAX_PRIORITY    = 10 //최대 우선순위 
public static final int MIN_PRIORITY     =  1 //최소 우선순위 
public static final int NORM_PRIORITY  =  5 //보통 우선순위 


쓰레드가  가질 수 있는 우선순위 범위는 1~10이고 숫자가 높을수록 우선순위가 높다. 

알아둬야할건 쓰레드의 우선순위는 쓰레드를 생성한 쓰레드로부터 상속받는다는 것이다. 


main메서드를 수행하는 쓰레드를 우선순위가 5이므로 main메서드 내에서 생성하는 쓰레드의 우선순위는 자동적으로 5가 된다.


-->우선순위는 쓰레드를 실행하기 전에만 변경할수 있다! 

그치만 

(싱글 코어 가정)

두쓰레드의 우선순위가 같은경우시 작업하는것과 

t1이 t2보다 우선순위가 높은경우 에 작업하는것을 비교한다면 


우선순위가 같은 겨웅네는 각쓰레드에 거의 같은 양의 실행시간이 주어지지만, 

우선순위가 다르다면 우선순위가 높은 t1에게 상대적으로 t2보다 많은 양의 실행시간이 주어지고

-->결과적으로 작업 A(t1담당)가 작업 B(t2담당)보다  더 빨리 완료될수 있다. 


그러나 멀티코어에서는 쓰레드의 우선순위에 따른 차이가 거의 없었다. 

-->쓰레드에 높은 우선순위를 주면 더 많은 실행시간과 실행기회를 갖게될거라고 기대할수는 없다는거..ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 


그래서 굳이 우선순위에 차등을 두어 쓰레드를 실행하려면, 특정 OS의 스케쥴링 정책과 JVM의 구현을 직접확인해 봐야하는데 


차라리 쓰레드에 우선순위를 부여하는 대신 작업에 우선순위를 두어서 Priority Queue에 저장해놓고, 우선순위가 높은 작업이 먼저 처리되도록

하는게 나을수도 있다.! 



:
Posted by Gongdile

저번에 멀티쓰레드와 멀티프로세스에 관해서 설명한적이 있는데 

이번에는 싱글쓰레드와 멀티쓰레드에 관해 다뤄보려고한다.


그전에 컨텍스 스위칭에대해 알고넘어가사 


컨텍스트 스위칭(context switching)이란 프로세스 또는 쓰레드 간의 작업 전환을 말한다. 


<가정을 해보자> 

두개의 작업을 

-하나의 쓰레드(t1)로 처리하는 경우 

-두 개의 쓰레드로 처리하는경우(t1,t2)


t1으로 두 작업을 처리하는 경우는 한 작업을 마친후에 다른 작업을 시작한다.

t1,t2으로 작업하는 경우 짧은시간동안 2개의 쓰레드가 번갈아가며 작업을 수행해서 동시에 두작업이 처리되는 것과 같이 느끼게한다.


싱글코어에서 싱글쓰레드 프로세스와 멀티쓰레드 프로세스를 비교하면 


두 경우다 작업을 수행한 시간은 거의 같다. 

오히려 두 개의 쓰레드로 작업한 시간이 싱글쓰레드로 작업한 시간보다 더 걸리는데 

그 이유는 

쓰레드간 작업전환(context switching)에 시간이 걸리기 때문이다. 

작업전환을 할대는 현재 진행 중인 작업의 상태등을 저장하고 읽어 오는 시간이 소요된다. 

(쓰레드 스위칭에 비해 프로세스 스위칭이 더 많은 정보 저장해야하므로 더 많은 시간이 소요됨!)


그래서 싱글코어에서 단순 cpu만을 사용하는 계산작업이라면 오히려 멀티쓰레드보다 싱글쓰레드로 프로그래밍 하는게 더 효율적이다.


두 개의 쓰레드로 작업하는데 더 많은 시간이 걸린 이유는 두가지다.

(1)두 쓰레드가 번갈아가며 작업을 처리하기에 쓰레드간 작업전환시간이 소요됨

(2)한 쓰레드가 화면에 출력하고 있는 동안 다른 쓰레드는 출력이 끝나기 기다려야하는데 이때 발생하는 대기시간 때문이다.



여러 쓰레드가 여러 작업을 동시에 진행하는 것을 병행(concurrent)라고 하고, 

하나의 작업을 여러 쓰레드가 나눠서 처리하는 것을 병렬(parallel)이라고 한다. 




1.싱글코어로 두 개의 쓰레드를 실행하는 경우와 

2.멀티코어로 두개의 쓰레드를 실행하는 경우에도 차이가 발생한다.


1의 경우는 멀티쓰레드라도 하나의 코어가 번갈아가며 작업을 수행하는 거라 두 작업이 절대 겹치지 않는다.

2의 경우는 멀티쓰레드로 두 작업을 수행하면, 동시에 두 쓰레드가 수행될 수 있으므로 

               두 작업, A와B가 겹치는 부분이 발생한다. 

--> 그래서 화면(console)이라는 자원을 놓고 두쓰레드가 경쟁하게된다. 

 

하지만 이런 결과는 실행할때마다 다른 결과를 얻을 수 있다. 

왜냐면 내가 실행하고있는 예제프로그램(프로세스)이 OS의 프로세스 스케줄러의 영향을 받기 때문이다. 


JVM이 쓰레드 스케줄러에 의해 어떤 쓰레드가 얼마동안 실행될건지 결정하는거와 같이 

프로세스도 프로세스 스케줄러에 의해서 실행순서와 실행시간이 결정되기 때문에 


매 순간 상황에 따라 프로세스 할당되는 실행시간이 일정치않고, 쓰레드에게 할당되는 시간 도한 일정하지 않다. 

--> 그래서 쓰레드가 이런 불확실성을 가지고 있다는 것을 염두에 둬야한다.


자바가 OS에 독립적이라곤 하지만 실제로는 OS종속적인 부분이 몇가지 있는데 쓰레드도 그 중의 하나이다.

(JVM종류에 따라 쓰레드 스케줄러의 구현 방법도 다를수 있다.)


..그림 나중에 첨부해야지!! 



두 쓰레드가 서로 다른 자원 사용하는 작업의 경우는 싱글쓰레드 프로세스보다 멅이쓰레드 프로세스가 더 효율적이다. 


ex)) 사용자로부터 데이터 입력받는 작업, 네트워크 파일 주고받는 작업, 프린터로 파일 출력하는 작업 

-->외부기기와의 입출력을 필요로 하는경우 


(A)사용자로부터 입력받는 작업

(B)화면에 출력하는 작업 


이 두가지를 하나의 쓰레드로 처리하면 사용자가 입력을 마칠 때까지 아무 일도 하지 못하고 기다려야한다. 

그러나 두 개의 쓰레드로 처리하면 사용자 입력 기다리는 동안 다른 쓰레드가 작업을 처리할 수 잇기 때문에 보다 효율적인 cpu사용이 가능하다.



:
Posted by Gongdile

]저번 포스팅에서 쓰레드(Thread)가 무엇인지에 관해서 설명했다. 

 [JAVA]Thread(쓰레드)- 1.Thread란 무엇일까? 정의,멀티쓰레드와 멀티프로세스

 -->http://gongstudyit.tistory.com/archive/20180515



이번에는 쓰레드를 구현하고 실행하는 방법 그외에 쓰레드의 우선순위, 실행주기등에 대해서 설명하려고한다.


자바에서 스레들르 만들기 위해서는 두가지 작업을 해야한다.

  • 스레드 코드 작성
  • JVM에게 스레드를 생성하여 스레드 코드를 실행 하도록 요청 
--> 자바에서 스레드를 만드는 방법에는 두가지가 있다.

1. Thread 클래스 상속
2. Runnable 인터페이스 구현 

어느 쪽을 선택해도 별 차이는 없지만 
쓰레드 클래스를 상속받으면 다른 클래스를 상속받을 수 없기 때문에 (자바에서는 단일상속만 허용! )
Runnable인터페이스 구현이 일반적이다. 

// 1. Thread클래스를 상속
class MyThread extends Thread{
   public void run() {/* 작업내용   */ }  //Thread클래스의 run( ) 을 오버라이딩
}
// 2. Runnable클래스를 상속
class MyThread implements Runnable{
  public void run() {/*  작업내용 */ } //Runnable인터페이스의 추상메서드 run()을 구현 
}

Runnable 인터페이스는 오로지 run( ) 만 구현되어있는 간단한 인터페이스라서 

구현하기 위해서는 추상메서드인 run의 몸통 { } 을 만들어주면 된다. 


쓰레드 구현하는 2가지 방법의 차이는 

Thread 클래스를 상속받은 경우와 Runnable 인터페이스를 구현한 경우의 인스턴스 생성 방법이 다르다.


아래 예제를 보자 

public class ThreadEx1 {

	public static void main(String[] args) {
		ThreadEx1_1 t1 = new ThreadEx1_1(); //Thread의 자손 클래스 인스턴스 생성
		
		Runnable r = new ThreadEx1_2(); //Runnable을 구현한 클래스의 인스턴스 생성
		Thread t2 = new Thread(r); //생성자 Thread(Runnable target)
		
  //저위의 두줄을 한줄로 간단하게 하려면..r 대신에 new ThreadEx1_2()를 넣으면 된다. 
	        t1.start();
		t2.start();
	}

}
class ThreadEx1_1 extends Thread{
	public void run() {
		for(int i=0; i<3; i++) {
			System.out.println(getName());//조상인 Thread의 getName()을 호출 
		}
	}
}

class ThreadEx1_2 implements Runnable{
	public void run() {
		for(int i=0; i<3; i++) {
			//Thread.currentThread() - 현재 실행중인 Thread를 반환한다. 
			System.out.println(Thread.currentThread().getName());//조상인 Thread의 getName()을 호출 
		}
	}
}
<실행결과>
Thread-0
Thread-0
Thread-0
Thread-1
Thread-1
Thread-1

Runnable인터페이스를 구현한경우, 구현한 클래스의 인스턴스를 생성한 다음에 (위의 r처럼)

이 인스턴스를 Thread클래스의  생성자의 매개변수로 제공해야한다. 


Thread클래스를 상속받으면, 자손 클래스에서 조상인 쓰레드 클레스의 메소드를 직접 호출할수있지만.

Runnable을 구현하면 쓰레드 클래스의 static 메서드인 current Thread( )를 호출하여 쓰레드에 대한 참조를 얻어와야만

호출이 가능하다. 


그래서 위의 예제에 ThreadEx1_2에는 멤버라고는 run( )밖에 없기 때문에

 'Thread.currentThread().getName()'와 같이 해야한다.


  • static Thread currentThread( ) 현재 실행중인 쓰레드의 참조를 반환한다.
  • String getName( )                 쓰레드의 이름을 반환한다. 


<쓰레드의 실행 - start( ) >

start( ) 를 호출해야만 쓰레드가 실행된다. 
start( ) 를 호출했다고 바로 실행되는건 아니고 실행대기에 있다가 자신의 차례가 되어야 실행된다.!

여기서 알아둬야할건 한번 실행이 종료된 쓰레드는 다시 실행할수없다.
즉, 하나의 쓰레드에 대해 start( )가 한 번만 호출될 수 있다. 
그래서 내가 만약 쓰레드의 작업을 한번 더 수행해야 한다면 
 --> 새로운 쓰레드를 생성한다음에 start( ) 를 호출해야한다.

하나의 쓰레드에 대해 start( )를 두번 이상 호출하면 실행시에 IllegalThreadStateException이 발생한다. 

이렇게 에러가 발생!! 


이렇게 만들어줘야한다 

그리고 쓰레드의 이름을 지정하지 않아서 'Thread-번호'의 형식으로 정해져서 콘솔에 출력된건데. 이거 내가 바꿔줄수있다.

다음과같은 생성자나 메서드를 통해서 지정또는 변경할수있다.

Thread(Runnable target, String name)
Thread(String name)
void setName(String name)

아까 위의 코드에서 System.out.println(Thread.currentThread().getName())은 

아래의 코드를 줄여 쓴 것이라고 이해하면 된다. 
Thread t= Thread.currentThread(); //현재 실행중인 쓰레드의 참조를 반환해서 t에 넣는다.
String name= t.getName(); //쓰레드의 이름을 얻어서 name에 넣는다.
System.out.println(name); //name 을 출력한다. 

이렇게 이용할수있다. 


근데 여기서 주의할거는 쓰레드 1, 쓰레드 2가 돌아간다고 가정할때 1,2의 네임을 똑같이 해주면 

어떤 쓰레드가 돌아가고있는지 네임을 얻어서 콘솔창에서 찍을때 알수가없다


 


그러면 스레드1 스레드2의 이름은 다르게하고 스레드1을 두번 실행했을때는 어떨까??

당연한 얘기지만 Thread_Ex3에서 set해준 네임그대로 찍혀나온다.


결론은 

아까 위에서 한쓰레드 대해 start( )가 한번만 호출될수있는데 

만일 쓰레드 작업을 한번더 수행해야할때 새로운 쓰레드를 만들어서 start( )를 호출했는데


그때 

thread -0

thread -1이라고나온건 내가 쓰레드 이름을 설정해주기 않았기때문에 그렇게 나온거라는걸 얘기하고싶었다. 


맨처음 예제에서 쓰레드를 상속받아 구현한것과 러너블 인터페이스를 구현한것도 출력결과가 

thread-0

thread-1이라고 나왔는데 


이것도 이름을 설정해주지 않아서인데 이름을 설정하게되면 다른스레드는 서로 다른이름으로 찍히겠지만, 

같은 쓰레드는 같은 이름으로 나온다는걸 (혼동할수있을거같아서) 설명했다.



<start( )와 run( )>


코드에 start( ) 와 run( ) 이 자주 등장했는데 둘에대해 설명하려고 한다.


main메서드에서 run( )을 호출하는 것은 생성된 쓰레드를 실행시키는게 아니라 

                                                     -->단순히 클래스에 선언된 메서드를 호출하는거다.


반면에 start( )는 새로운 쓰레드가 작업을 실행하는데 필요한 호출스택(call stack)을 생성한 다음에 

                                                     -->run( )을 호출해서, 생성된 호출스택에 run( )이 첫번째로 올라가게 한다.


뭔말이냐?? 면..! 


맨위에 예시처럼 우리가 스레드를 상속받아서 구현시에 run( ) 이라는 메소드를 오버라이딩 했는데 

run( )을 스레드코드 라고부른다. 

스레드는 run( ) 메소드에서부터 실행을 시작하고 run( ) 이 종료하면 스레드도 종료한다.

-->(만약 run( )을 오버라이딩 하지 않으면) Thread클래스의 run( )이 실행되며 Thread의 run( )은 아무일도 하지x 

    단순 리턴하도록 작성되어 있어서 스레드가 바로 종료된다. 


그러니까 쓰레드를 상속받아서 run()이라는 메소드를 오버라이딩해서 스레드 코드를 작성한다. 

그리고 스레드 객체를 생성한거에 생명력을 가지고 실행하게 하는게 바로  start다 !! 



start( )메소드를 호출함으로써 스레드를 동작시킨다. 

(start( )메소드는 Thread클래스에 구현된 메소드이며 개발자가 오버라이딩하면 안된다.)


start( )메소드가 생성된 스레드 객체를 스케줄링이 가능한 상태로 전환하도록 JVM에게 지시를 한다. 

이후 스케줄링에 의해서 그 스레드가 선택되면 비로소 JVM에 의해 run( )메소드가 호출되어 실행을 시작한다.!! 


:
Posted by Gongdile

Thread란 뭘까? 


책에서 스레드 관련 목차를 보면 

1.프로세스와 쓰레드 //그냥 쓰레드랑 멀티쓰레드를 한번에 묶어서 설명한 책도있다.!  

2. 쓰레드의 구현과 실행 

3.싱글쓰레드와 멀티쓰레드 

이후에 쓰레드의 우선순위, 쓰레드의 그룹, 데몬쓰레드 실행제어 동기화등이 설명되어있다.



예전에 한번 블로그에서 동기화에 관해서 앞부분만 설명했는데 오늘은 쓰레드에 관해서 정의나 앞에 전반적인 부분에 대해서 설명하려고 한다. 언어는 볼때마다 기분이 새롭다 ~_~ 




Thread는 한글로 직역하면 '실'이다. 바느질할때 사용하는 ! 

바늘에 실을 꿰어놓으면 오직 그 하나의 실로 하나의 작업을 할 수 있다. 만약에 내가 실로 두가지 바느질을 동시에 하려면 실(thread)가 따로 필요하다.  


컴퓨터 용어로 사용되는 스레드는 실의 의미와 일맥상통한다. 

--> 자바에서 상속부분에서 extends는 확장하다 라는의미인데 조상클래스에서 자식클래스로 갈수록 확장한다는 개념에서 extends라는 단어를 받아들이면 용어가 이해하기 더 쉬운데 스레드도 그런 의미해서 이해하면 더 받아들이기 쉽다. 


컴퓨터에서 사용하는 스레드(thread)는 thread of control의 준말로. 프로그램 코드를 이용하면서 실행하는 하나의 실 

혹은 제어의 개념이다. 아까 말한것처럼. 하나의 실로 하나의 바느질 밖에 할 수 없듯이 하나의 스레드로 하나의 작업밖에 처리할 수 없다. 


쓰레드 부분을 공부하면  프로세스에 대해서도 알고있으면 좋은데.. 


그전에 

프로세스와 프로그램의 차이를 알고있어야한다.

사실 여기서 운영체제(OS) 부분으로 들어가면 프로그램과 프로세스 차이에 대해 더 자세하게 정리할수있지만..

나는 쓰레드에서 프로세스와 프로그램의 차이를 간단하게 집고 넘어갈꺼라 추후에 정리하도록 하겠다.


  • 프로그램(Program) -->실행 가능한 파일
  • 프로세스(Process) -->실행 중인(Running) 프로그램(메모리)


이렇게 프로그램을 --->(실행)하면  --> 프로세스 


프로세스는: 실행중인 프로그램을 말한다. 자원(resources)과 쓰레드로 구성된다. 

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


쓰레드한마디로 말하자면 실행의 단위이다. 


프로세스가 공장이라면.. 쓰레드는 일꾼이랄까 


모든 프로세스에는 최소한 하나 이상의 쓰레드가 존재한다. 

둘 이상의 쓰레드를 가진 프로세스를 (Multi-threaded process)라고한다. 


하나의 프로세스가 가질 수 있는 쓰레드의 개수는 제한되있지는 않으나. 

쓰레드가 작업을 수행하는데 개별적인 메모리 공간(호출 스택)을 필요로 하기 때문에 

프로세스 메모리 한계에 따라 생성할 수 있는 쓰레드 수가 결정된다.

(근데 실제로 그정도로 많은 쓰레드를 생성하는 일은 없을거다 ㅋㅅㅋ)


멀티프로세스(multi-processing)와 멀티쓰레드(multi-threading)를 비교하자면. 

하나의 새로운 프로세스를 생성하는 것보다 하나의 새로운 쓰레드를 생성하는게 

더 적은 비용이 든다.  그러나 멀티쓰레드도 단점이있다. 그건 아래에 정리하겠다 ! 


---> 멀티프로세스는 하나의 응용프로그램이 여러 개의 프로세스(process)로 구성하여 각 프로세스가 

하나의 작업(task)를 처리하도록 하는 기법이다. 


위에 그림처럼 각 프로세스는 고유한 메모리 영역을 독립적으로 실행된다. 그러므로 하나의 응용프로그램에 속하는 프로세스들조차 상호통신 오버헤드가 크고 프로세스의 문맥교환(context switch)에 따른 과도한 작업량과 시간 소모의 문제점이 있다. (밑줄친 부분을 몰라도 괜찮다. 자바 예제 하는데 지장없다.)


이러한 문제점을 개선하기 위해 제안된 방법이 멀티스레드다!! 


---> 멀티스레드는 하나의 응용프로그램을 여러 개의 스레드로 구성하고 각 스레드로 하여금 하나의 작업을 처리하도록 하는 기법이다.


모든 스레드가 응용프로그램 내의 자원과 메모리를 공유하므로 통신에 따른 오버헤드가 비교적 크지 않고, 스레드 사이의 문맥교환 시에 작업량이 작고 시간이 짧은 장점을 지닌다. 

멀티스레딩시에 운영체제의 스케쥴링 단위가 스레드인셈이다. 


윈도우나 리눅스등 많은 os가 멀티프로세스를 지원하고 있지만 멀티스레드을 기본으로 하고있다. 


멀티쓰레드의 장단점을 얘기하자면 


<장점>

-자원을 보다 효율적으로 사용가능

-사용자에 대한 응답성(response)가 향상

-작업이 분리되어 코드가 간결 


--> 여러모로 좋다!


<단점>

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

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

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


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

 




우리는 자바에서 스레드로 작동할 코드만 준비하면되고, 스레드의 실행을 책임지는건 JVM이다.

-->자바스레드(java thread)는 JVM에 의해 스케줄되는 실행단위의 코드블록이다. 


자바에서 jvm(자바 가상 머신)은 멀티스레드를 지원하기때문에 자바 응용프로그램은 하나 이상의 스레드를 생성할수있다. 스레드가 생성되면 스레드에 관련된 정보 (Thread Control Block, TCB)가 생성되는데 JVM이 관리한다.


JVM은 (1)한개의 응요프로그램만 실행 가능하다. -->여러개 응용프로그램 실행 불가 X 

    (2)하나의 응용프로그램이 여러 개의 스레드를 가질 수 있다.! 


우리는 이제 이 스레드를 어떻게 사용할지 만드는 방법에 대해서 알고있으면 된다!  구현하는 방법! 





이번 내용을 통해서 내가 결론적으로 말하고싶은건


  • 쓰레드라는건 실행의 단위이고(실!!! ) 

  • 프로세스와 프로그램, 멀티프로세스와 멀티쓰레드의 차이를 알았다는거 !! 

  • 멀티쓰레딩을 이용하여 프로그램 실행시에 장점과 단점이 있기에 고려를 해야한다는점 

  • 그리고 자바에서 스레드의 실행을 책임지는건 JVM이기 때문에 우리는 

    작동시킬 코드만 준비하면 된다는 점이다. 


--> 다음번에는  스레드 구현에 대해서 설명하겠다. 





  


그림 출처: -http://good-dba.tistory.com/9 -->티스토리 

              -자바의정석 PPT 참고 !! 




:
Posted by Gongdile

실습문제 정리하려고한다.

스레드는 내가 공부를 처음하는 부분이라서  

익숙하지가 않아서 정리도 좀하고..봐야겠다.. 


선생님과 같이풀었던 실습문제들 정리. .. 


이 문제를 보고 일단 생각해야할건.. 

1. 문자열을 0으로 설정하고 

2.레이블 클릭시 0.1초에 1씩 증가하는 카운팅. 

3.다시한번 클릭시 카운팅 중단 -->그리고 처음부터 시작.


스레드 중지시키기 위해서 interrupt( )메소드를 사용하고 

스레드가 살아 있는지 확인 위해서는 Thread.is Alive( )메소드 이용 


그럼일단 Swing을 이용해서 프로그램을 짠다. 

프로그램 클래스명 이름은 CountingControlFrame.java 라고 설정하겠다. 


자바의 GUI응용프로그램중에서 Swing을 사용하는것인데.. 프레임이나 컴포넌트 관련한 설명은 

추후에 설명하겠다. (왜냐면 이거 정리하는것도... 시간이 ㅋ_ㅋ )!! 


저 문제 프로그램의 구성블록을 그냥 캡처안에서 여기서 바로 정리했다 그림판으로.. 관계에 대해서

이해하려는 이유로 정리했다 저 네모박스는 { } 을 의미한다.

관계가 한눈에 들어오겠죠!! 


이런식으로 지금 프로그램이 구성되어있다. 코드는 주석으로 상세하게 설명했다. 

보고 참고하기.. 

파일첨부는 언젠가.. 

겉에 보이는 폼을 만들어준 부분이다.. 이제 안에 코드를 넣어야겠지.



코드가 잘보이는지 모르겠다... 이런 관계로 이러지는건데 


boolean bPaused =true;는 불리언 논리형은 디폴트값이 false인데 true로 초기화해주고 선언한거다.

내가 만약에 초기값을 true로 선언해주지않으면 기본값이 false기때문에 

아래 while문에서 실행이되지않으므로 프로그램 실행시 초가 증가하지 않는다. 


else 아래 Thread.start( ); 부분이 보이나? 

스레드는 한번 죽으면 새로 만들어야한다. ->다시 중지했다가 시작하고 이런게 아니다.

run이끝나면 무조건 쓰레드는 무조건 사라지므로 else if, else 는 내가 해줘야하는 부분이다.


new스레드에서 스레드가 만들어져서 변수가 스레드를 가르킨다. 

근데 이 스레드가 끝나면 사라져버린다.. 

그렇다고 변수값이 바뀌냐?? -->NO! 안바뀐다.!! 100번지 들어있다가 200번지되냐? 아니다.

왜냐하면 스레드가 NULL이 아니기 대문에... NULL은 아니고 죽어있으니까 다시 붙이면된다.

스레드가  한번 만들어서 죽어버리면 Null이 안된다. 

처음에는 null이다 그래서처음에 if문으로 null일때 만들어준거다. 


하지만 만들었을때 100번지를 가르키면 얘는 100번지를 가지고있을거다.

사라지더라도 타이머스레드의 100이라는 주소는 존재한다. 


스레드가 살았냐~ 죽었냐~ 로 판단하는거다.. 


다음은 이제 아래의 run code를 보자 


여기서 while(true)말고 

while(bPaused)라고해도 돌아간다. 


러너블이라는 인터페이스를 상속받았기 때문에 런이라는 메소드를 오버라이딩 해줘야한다. 

-->인터페이스, 상속, 오버라이딩 이라는 부분이 이해가 안가시는분은 구글링이나 검색을 .. 해보셔야한다!! 


오버라이딩은 부모에게 상속받은 메소드를 or 클래스를 내입에 맞게 재정의해서..사용하는걸 말한다


인터페이스를 사용하면 꼭 그안에있는 메소드나 클래스를 구현해줘야하는데 


나는 스레드에서 러너블이라는 인터페이스를 사용한 클래스를 만들었기 때문에 

지금 런이라는 메소드를 오버라이딩 해주고있는거다. 


런이 실행되는게 true면 0에서부터 value값을 증가해주는거고 

인터럽트가 걸리면 캐치문에서 원래 value초기값을 주고 끝내버린다. 



마지막으로 메인함수에서 내가만든 프레임을 실행한다고 new! 해주면 메인에서 돌아간다

메인에서 countingcontrolframe()을 실행시키면 아까 위에서 내가 만든 함수를 타고 생성된다..

겉껍데기 만들고 안에 돌아가는거 해주고 저 맨위에 그림을 보면서 전반적으로 구조를 판단하기.. 


실행하면 마우스 클릭시 실행되면서 숫자가 점점 올라가고 다시 클릭하면 0으로 초기화된다. 


:
Posted by Gongdile

쓰레드의 동기화(synchronization)이란 뭘까? 

--> 한스레드가 진행중인 작업을 다른 쓰레드가 간석하지 못하도록 막는것을 말한다.


왜쓸까? 


싱글스레드 프로세스 경우는 프로세스 내에서 단하나의 스레드만 작업하기 때문에 

프로세스의 자원을 가지고 작업하는데 별 문제가 없다. 


하지만 

멀티스레드의경우에는 여러 스레드가 같은 프로세스 내의 자원을 공유해서 작업하기 때문에 

서로의 작업에 영향을 주게된다. 


예를들면 

ATM에 통장에 50만원이있었는데 각 다른 두곳에서 출금한다고 가정하자 ㅋㅋ 

동시에 두곳에서 50만원이 출금되면 정말 행복하겟지만.. 

은행입장에서는 큰일나는거 아닌가 ..ㅋㅋㅋ 


A atm기에서 작업을 실행할대 락을 걸어서 다른 곳은 접근못하게하고 출금이 다끝난뒤에 

접근권을 획득해서 B atm기가 출금해야 이중으로 출금되는것을 막을수있다. 

--------------------------------------------------------------------------------------------


그래서 스레드에서는 저런 일이 방지하는것을 막기위해서


한 쓰레드가 특정 작업을 끝마치기 전까지 다른 쓰레드에 의해 방해받지 않도록 하는것이 필요한데


그래서 도입된 개념이 '임계 영역(critical section)'과 '잠금(락,lock)'이다.


->공유 데이터를 사용하는 코드 영역을 임계 영역으로 지정해놓고, 공유 데이터(객체)가 

가지고 있는 lock을 획득한 단 하나의 쓰레드만 이 영역 내의 코드를 수행할 수 있게 한다.

그리고 해당 쓰레드가  임계 영역 내의; 모든 코드를 수행하고 벗어나서 lock을 반납해야만 

다른 쓰레드가 반납된 lock을 획득하여 임계 영역의 코드를 수행할 수 있게 된다. 


-------------->위에서 말한것처럼 이런 한 쓰레드가 진행 중인 작업을 다른 쓰레드가 간석하지 못하도록 막는것을!! 

'쓰레드의 동기화(Synchronization)' 라고 한다.   


동기화 방법에는 여러가지가있다. synchronized를 이용한 방식, wait ( ) , notify( ) , notifyAll( ) 를 이용한 방식.. 

여러가지가있는데 오늘은  synchronized를 이용한 방식에 대해 설명할 예정이다.. 

(여러개를 포스팅하고싶지만.. 힘들다 ㅠㅠ 조금이라도 꾸준히 올리는게 목표다)


1.synchronized를 이용한 동기화 


가장 간단한 동기화 방법인 synchronized 키워드를 이용한 동기화에 대해서 알아보면 

이 키워드는 임계 영역을 설정하는데 사용된다. -->두가지 방식이있다. (사진이 생각보다 짱큰게 올라갔다)


<첫 번째 방법>

메서드 앞에 synchronized를 붙이는방법 

synchronized를 붙이면 메서드 전체가 임계영역으로설정된다. 

쓰레드는 synchronized메서드가 호출된 시점부터 해당 메서드가 포함된 객체의 lock을 얻어 작업을 수행한다.

메서드가 종료되면 lock을 반환한다.


<두 번째 방법>

메서드 내의 코드 일부를 블럭 { }으로 감사고 블럭 앞에 'synchronized(참조변수)'를 붙이는 방법

이때 참조변수는 --> 락을 걸고자하는 객체를 참조하는것이어야한다. 


이 {  }블럭을 synchronized블럭이라고 한다. 

->이 블럭의 영역 안으로 들어가면서부터 쓰레드는 지정된 객체의 lock을 얻게되고. 

   블럭을 벗어나면 lock을 반납한다.


-----------

두 방법 모두 lock을 하나씩 가지고 있다.

해당 객체의 lock을 가지고 있는 쓰레드만 임계 영역의 코드를 수행할 수 있다.

그리고 다른 쓰레드들은 lock을 얻을 때가지 기다리게 된다.

------

임계 영역은 멀티쓰레드 프로그램의 성능을 좌우하기 때문에 가능하면 메서드 전체에 락을 거는것보다 

synchronized블럭으로 임계 영역을 최소화해서 효율적인 프로그램이 되도록 노력하는게 좋다.



아래는 synchronized 사용예제에 대해서 설명할거다 


쓰레드 동기화를 사용한 경우와 사용하지 않은 경우의 차이를 간단한 예제를 통해서 설명하려고한다.


공쓰레드와 다일쓰레드가 사용하는 부분을 보여줄 예정이다. 



위에 소스는 

gong과 dile이라는 이름의 스레드를 생성하여 집계판에 동시에 접근하게 한것이다. 

그리고 두 스레드를 실행시키는 부분이다. 


위에 소스와 이어서 타이핑 친부분이다 아래는 

공유 데이터인 집계판을 시물레이션하는 클래스를 만든거다.

이제 아래 소스를 보자 


최종적으로 소스에 흐름에 대해서 설명하자면 


SyncObject멤버 add( )를 synchronized 메소드로 지정했다. 

왜??!

-->add ( )는 두명의 gong,dile 즉 WorkerThread 스레드가 동시에 호출할수있는 임계영역이기 때문이다.

    또한 add( ) 메소드는 sum 공유변수에 접근하고 있기 때문이다. 


WorkerThread는 루프를 돌면서 27번줄에 SyncObject의 add( )메소드를 호출하여 

SyncObject의 sum 멤버 값에 10을 더하고 리턴한다. 

main은 이름이 "gong","dile"인 두개의 WorkerThread 스레드를 생성한다. 


최종 sum이 얼마일꺼같나? ㅋㅋ -->200이다!! 왜??1 

gong와 dile이가 각각 10번씩 add( )를 호출했기때문에 

동기화가 잘이루어진다면 최종 누적점수 sum이 200이 된다. 


그림으로 표현하면 이렇다.. 


어떤 형식으로 찍힐까?

이런식으로 gong과 dile이가 순차적으로 sum되가면서 찍힌다. 


근데 만약에 synchronized키워드를 제거하게 되면 어떻게 출력될까?


실행할때마다 다르긴한데  충돌이된 예시를 보여주자면 


위에 네모박스처럼 add( ) 메소드에 충돌이 생긴경우다

-->이때문에 10이 증가되지못했다.


아래 밑줄처럼 두 스레드의 add(  ) 메소드에 대한 동시 실행으로 인해 190밖에 도달하지 못했다.


근데 저 코드를 맨날 실행한다고 같은 결과가 나오는건 아니다 

여러번 충돌할수도있는거고 충돌안할수도있는거고 하지만 동기화를 해주지 않으면

충돌할 위험이 있기 때문에 해줘야한다. 


두개의 스레드가 동시에 호출할 경우가 발생할 위험이있기때문에 동기화 처리를 해주는거다. 


2.wait( )과 notify( )를 이용한 방식 은 나중에 정리하겠다!! 


:
Posted by Gongdile


-Scanner.nextInt 메소드는 

-->가장 마지막 개행문자(엔터,newline)을 제거하지않는다.


개행문자(엔터)전까지만 숫자로 입력받음.


-->이부분에서 문제가 생김 


nextInt( )와 nextLine( )을 사용시 

넥스트인트에 5를 입력하고 엔터친다고 가정하면

넥스트라인 안에 공백이 입력으로 처리되서 문제가 발생함  


nextLine( )은 한줄을 입력받는다. 


이해를 돕기위해 사진을 첨부하겠다.


이렇게 5입력시에 엔터를 치면 공백이 b안에 들어가서 b가 아무것도 찍히지 않게 된다 


어떻게 해결할꺼냐..?



<1. 중간에 scan.nextLine(  ); 삽입하기>




a와 b입력 사이에 scan.nextLine( )을 하나 넣어서 개행(엔터)를 처리해주는 방법으로 하면


잘출력된다.. 


<2.nextLine( )으로 받아서 parseInt로 변경해서 출력하는 방법>



이 글을 읽는 어떤분중에는..

어그러면 그냥 a를 scan.nextLine( )으로 받음 안됨?! 할수도있을거같은데.. NO!! 



 이런 에러가 친절하게 떠요 ㅎㅎ ! 


--> Line은 String에서 쓸수있습니다. 


Scanner 클래스는 자바에서 제공해주는 클래스인데 

화면, 파일, 문자열과 같은 입력소스로부터 문자데이터 읽어오는데 도움줄 목적으로 추가된거에요. 


자세한 설명은 생략하고 Scanner사용시에는 데이터 형식에 맞는 메서드를 사용해줘야합니다.. 

이건 표로 정리하겠습니다.


[표 - 데이터형식과 Scanner메서드]


 

 형식

메소드 
 논리형

boolean (

nextBoolean( ) 

 정수형

byte 

nextByte( ) 

short 

nextShort( ) 

int 

nextInt( ) 

long 

nextLong( ) 

 실수형

double 

nextDouble( ) 

float 

nextFloat( ) 

 문자

String 

next( ) //띄어쓰기로 구분

nextLine(  ) // 한 문장 전체, 엔터키로 구분



맞게 사용하시면 되요.. 


<3. 스캐너를 두개받는 방법>



스캐너를 사용하는 방법이다..


개인적으로는 그냥 중간에 Scan.nextLine( )삽입하는게 제일 편하다고 생각한다.! 


정리하는데 은근 시간을 많이.. 무튼 정리 끝!



:
Posted by Gongdile
2018. 1. 15. 23:27

배열 스터디 Programming Language/Java2018. 1. 15. 23:27

제가 오늘 설명해드릴건 배열(Array)입니다.

1.배열이란? 2.배열의 선언과 생성 3.배열의 길이와 인덱스

4.배열의 초기화 5.배열의 복사 6.배열의 활용

[1]배열이란?..

책에는 배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것이라고 써져있는데 좀더 자세하게 얘기하면(이것이자바다,명품에센셜)

à같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에(index)를 부여해 놓은 자료구조

중요한건 1) ‘같은타입이어야 한다는 거고, 2)서로 다른 타입의 변수들로 구성된 배열 만들수없다.

변수와 달리 배열은 각 저장공간이 연속적으로 배치되어있다.

그리고 int배열은 int값만 저장 가능하고 String배열은 문자열만 저장가능하다. 배열은 선언과 동시에 저장할 수 있는 데이터 타입이 결정되기 때문에, 만약 다른 타이브이 값을 저장하려고 하면 타입 불일치(Type mismatch)컴파일 오류가 발생한다.

배열의 또 다른 특징은 한번생성된 배열은 길이를 늘리거나 줄일 수 없다..그래서 3개의 값을 저장하는 배열을 생성했다고 가정하면 프로그램 실행도중에 5개의 값 저장하는 배열로 수정x 반대로 2개의 값만 저장하는 배열로도 수정ㅌ 그래서 5개의 값을 저장하는 경우가 발생하면 길이 5의 새로운 배열을 생성하고, 기존 배열 항목을 새 배열로 복사해야한다..

이것으로 배열은 같은 타입의 데이터를 연속된 공간에 나열시키고, 각 데이터에(index)를 부여해 놓은 자료구조이고 1)같은 타입의 데이터만 저장할 수 있으며2)한번 생성된 배열은 길이를 늘리거나 줄일 수 없다는 것을 알 수 있다.. ㅇㅋ?

[2]배열의 선언과 생성

(1)배열의 선언

자바에서 배열을 생성할때는 두단계가 필요하다..

1.     배열에 대한 레퍼런스 변수(참조) 선언 2. 배열생성- 배열 공간 할당

배열에 선언에는 두가지 방법으로 선언이 가능하다 표[5-1]을 참고하면..

1.     타입[]변수이름; 2.타입 변수이름[]; 이렇게 원하는 타입의 변수를 선언하고 변수 또는 타입에 배열임을 의미하는 대괄호[]를 붙이면된다.

배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고,

배열의 주소값을 가질 뿐이지 아직 그 자체가 배열은 아니다. 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어진다.

à이건 이따 자세하게 설명하도록 하자

(2)배열의 생성

배열 생성은 배열 공간을 할당받는 과정이다. 반드시new연산자를 이용해서 배열을 생성하며 []안에 생성할 원소의 개수를 지정한다.//그러니까 배열을 생성하기 위해서는 연산자‘new’와 함께 배열의 타입과 길이를 지정해주어야 한다.

타입[] 변수이름; //배열을 선언(배열을 다루기 위한 참조변수 선언);

변수이름 = new 타입[길이]; //배열을 생성(실제 저장공간을 생성);

근데 보통 동시에 선언과 생성하는 방법을 이용한다.

타입[] 변수이름 = new 타입[길이];  à자세한 설명은 183 184 보기

[3]배열의 길이와 인덱스

1)인덱스

생성된 배열의 각 저장공간을 배열의 요소(element)라 하며 배열이름[인덱스]의 형식으로 배열의 요소에 접근한다. 인덱스는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용된다.

인덱스범위à 0부터 배열의길이 -1까지 [그림 5-3]설명하기 // 185쪽 설명도 설명하기

배열의 장점은 index로 상수 대신 변수나 수식도 사용할 수 있다는 것.. 186쪽 컴파일 에러 설명

2) 배열의길이

괄호안에 배열의 길이를 적어줘야하는데 배열의 생성 부분에서 얘기했음.. 배열의 길이는 배열의 요소의 개수, 즉 값을 저장할 수 있는 공간의 개수다. 양의 정수여야하고 0도포함임

배열사용할 때 오류날수있는경우는..1)배열범위넘어서접근 2)인덱스로 음수사용  3)배열이 생성 되되있지않은 사용할 때 à레퍼런스만 선언하고 사용할 때

Int intArray[]; // \n  intArray[1]=8; 이렇게 설명하면 갑자기 헤깔릴수있는데

예를들어서int intArray = new int[5]; 라고한다면 인덱스는0~4까지 가능.. 근데 여기서 인덱스는

인덱스 =배열크기 -1이라는거 

JVM이 배열의 길이를 관리하는데

배열길이 알려면 배열이름.length를 사용하면됨 더 편함 ..근데 기억할꺼는 p.187아래에 나오는데

배열이름.length는 상수다!  P.188하단~189상단 설명하기

length필드를 이용하면 프로그램에서 배열의 크기를 따로 관리할 필요가 없다

[4]배열의 초기화 

배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 되지만. 원하는 값을 저장하려면 요소마다 값을 지정해줘야하는데..이럴 때 {}사이에 원소를 나열해서 초기화된 배열을 만들 수 있다.

P190상단설명 ..출력할때는 190아래와 같은 방법아니면 191상단에

Arrays.toString(배열이름)메서드를 사용해도됨

[5]배열의 복사

배열의 길이를 변경하지 못하기 때문에 두가지 방법을 이용해서 배열을 복사할 수 있다.

(1)   for문을 이용해 배열 복사

(2)   System.arraycopy()를 이용한 배열의 복사

2번째 방법이 더 효율적임 p.192~p.195설명..

예제5-11예제를 설명하면서 length필드에 대해서 잘생각해야함

자바는 배열을 객체로 다룬다.. 배열 공간과 함께 배열의 크기 값을 가진 length필드가 배열 객체 내에 생성된다.. 객체로 관리되는 배열과 배열의 크기를 가진 length필드..

결론 배열의 모든값을 출력하려면

For(int i=0; i<intArray.length; i++)

System.out.println(intArray[i]); intArray배열 크기만큼 루프를 돈다.

배열의 길이가 n일 때 첫번째부터n-1까지 요소에 대해 비교하는데..비교횟수가 주니까n-1-i..

 

 

자바에서 지원하는 데이터타입에 대해서 알기..기본타입과 참조타입이있다.

기본타입이란 정수,실수,문자,논리리터럴을 저장하는 타입을 말한다.

우리는 기본타입으로 변수를 선언하고 데이터를 선언했었는데 참조타입이란 객체(Object)의 번지를 참조하는 타입으로 배열,열거,클래스,인터페이스 타입을 말한다.

기본타입으로 선언된 변수와 참조타입으로 선언된 변수의 차이점은 저장되는 값이 무엇이냐임

기본타입인 byte,char,short,int,long,float,double,boolean을 이용해서 선언된 변수는 실제값을 변수안에 저장하지만 참조타입인 배열,열거,클래스,인터페이스를 이용해서 선언된 변수는 메모리의 번지를 값으로 갖는다. à번지를 통해 객체를 참조한다는 뜻에서 참조 타입이라고 부른다.

Int double로 선언된 변수 age price가 있다면 이것은 직접 값을 저장하고있고

String클래스로 선언된 name hobby가있다고하면.. 힙영역의 String객체 주소 값을 가지고 있다.

변수가 스택 영역에 생성되고 객체는 힙역영에 생성된다는 것만 알아두기

à주소를 통해 객체를 참조한다는 뜻에서 String클래스 변수를 참조 타입 변수라고 한다.

JVM메모리 영역에 대해서 간단하게 설명해드릴껀데 java.exe JVM이 시작되면 JVM은 운영체제에서 할당받은 메모리영역(Runtime Data Area)을 세부영역으로 구분해서 사용한다..

1.     메소드 영역

2.     힙영역

3.     JVM(STACK)영역

여기서 힙영역에 대해서만 간단히 설명드리면

힙영역은 객체와 배열이 생성되는 영역임 힙영역에 생성된 객체와 배열은 JVM스택 영역의 변수나 다른 객체의 필드에서 참조됨 참조하는 변수나 필드가 없으면 의미없는 객체가 되기 때문에

쓰레기로 취급하고 가비지컬렉터가 힙영역에서 자동으로 제거한다 개발자가 별도로 제거해줄필요없고 코드에서 직접 제거시키는방법 제공하지않는다.

JVM스택영역..

한가지만 말하자면 프레임 내부에 로컬변수 스택이 있는데 기본타입 변수와 참조타입 변수가 추가(PUSH)되거나 제거(POP)된다. 변수가 이영역에 생성되는 시점은 초기화될 때, 즉 최초로 변수에 값이 저장될때이다. 변수는 선언된 블록안에서만 스택에 존재하고 블록을 벗어나면 스택에서 제거된다.

내가 이얘기를 왜 했냐면 배열변수는 참조변수에 속하낟. 그래서 배열도 객체이므로 힙영역에 생성되고 배열 변수는 힙영역의 배열객체를 참조하게된다. 참조할 배열 객체가 없다면 배열 변수는 NULL값으로 초기화될수있는데(타입[] 변수=null;) 상태에서 변수[인덱스]로 값을 읽거나 저장하면 NULLpointerexception à배열 변수는 배열을 생성하고 참조하는 상태에서 값을 저장하거나 읽어야함

:
Posted by Gongdile



:
Posted by Gongdile