본문 바로가기

Java

15 - 3장 쓰레드의 속성

1. 현재 쓰레드 객체 참좃값 얻어오기

 

 - Thread 클래스를 직접 정의하고 객체를 생성해 사용할 때 참조 변수를 이용해 언제든지 쓰레드 객체의 속성을 가져올 수 있음

 

- 객체를 참조할 수 없는 상황

  -> 직접 쓰레드 객체 생성 x ( 자바의 쓰레드 풀 or main 쓰레드)

  -> 객체를 생성할때 참조 변수를 정의하지 않은 경우 (new Threrad().start())

 

 - 쓰레드 객체를 참조할 수 없을 때 Thread 클래스의 정적 메서드currentThread()메서드를 이용해 

현재 쓰레드 객체의 참좃값을 얻어 올 수 있음

static Thread Thread.currentThread()

 

2. 실행 중인 쓰레드의 개수 가져오기 

 

 - 여러 개의 쓰레드가 실행되고 있을 때 현재 실행(active)중인 쓰레드의 개수 알고자 한다면,

 Thread 클래스 내의 정적 메서드 activeCount()를 사용

 

- activeCount() 

 -> 동일한 쓰레드 그룹 내에서 실행중인 쓰레드의 개수 리턴 

 -> 하나의 쓰레드에서 별도의 지정 없이 새로운 쓰레드를 생성하면 생성된 쓰레드는 생성한 쓰레드와 동일한 쓰레드 그룹에 위치 

static int Thread.activeCount()

 

3. 쓰레드의 이름 지정 및 가져오기 

 

- 직접 이름을 부여하려면 Thread 클래스의 인스턴스 메서드setName()메서드 사용

- 직접 지정하지 않으면 컴파일러가 대신해서 자동으로 부여 (thread - 숫자)

 

-setName()

 -> 인스턴스 메서드이므로 일단 쓰레드 객체를 생성한 후에 적용 가능 

String setName(String name)

 -getName()

  -> 직접 지정했거나 자동으로 부여된 쓰레드의 이름을 가져올 때인스턴스 메서드getName()사용

String getName()

 

- 쓰레드 객체의 속성 다루기 

package ThreadProperties;

//쓰레드 객체의 속성 다루기 

public class ThreadProperties {
	public static void main(String[] args) {
		
		//객체 참조하기, 쓰레드의 개수 가져오기 
		Thread curThread = Thread.currentThread();
		System.out.println("현재 쓰레드의 이름="+curThread.getName());
		System.out.println("동작하는 쓰레드의 개수="+Thread.activeCount());
		
		//쓰레드 이름 자동 지정
		for(int i=0;i<3;i++) {
			Thread thread = new Thread();
			System.out.println(thread.getName());
			thread.start();
		}
		
		//쓰레드 이름 직접 지정
		for(int i=0; i<3; i++) {
			Thread thread = new Thread();
			thread.setName(i+"번째 쓰레드");
			System.out.println(thread.getName());
			thread.start();
		}
		
		//쓰레드 이름 자동 지정 
		for(int i=0;i<3;i++) {
			Thread thread = new Thread();
			System.out.println(thread.getName());
			thread.start();
		}
		
		//쓰레드의 개수 가져오기 
		System.out.println("동작하는 쓰레드의 개수 = "+Thread.activeCount());
	}
}

 

4. 쓰레드의 우선순위 

 

 - 모든 쓰레드는 1~10사이의 우선순위를 갖고 있음

 - 기본값으로 5의 우선순위 

 

 - 자바 API에서 제공하는 Thread 클래스의 정의된 정적 상수 

   Thread.MIN_PRIORITY =1 

   Thread,NORM_PRIORITY =5

   Thread.MAX_PRIORITY =10

 

 - 우선순위는 쓰레드의 동시성과 관계가 있음 

 - 2개의 작업이 하나의 CPU 코어에서 동작할 때 쓰레드의 동시성에 따라 2개의 작업은 일정 시간 간격으로 번갈아가면서 실행

 - 우선수위가 높으면 상대적으로 더 많은 시간을 할당받게 됨

 - 동일한 작업량을 가진다면 우선수위가 높은 쓰레드가 먼저 끝날 것임 

 

 - setPriority()

  -> Thread 클래스의 인스턴스 메서드 

  -> 쓰레드 객체의 우선순위 정하기 

void setPriority(int priority)

 

-getPriority()

 -> Thread 클래스의 인스턴스 메서드 

 -> 쓰레드 객체의 우선순위 가져오기 

int getPriority()

 

- availableProcessors()

 -> 현재 컴퓨터의 CPU 코어 수를 알고 싶을 떄 

public native int availableProcessor();

 

- 쓰레드의 우선순위 

package ThreadProperties;

//우선순위 
class MyThread extends Thread {
	//Override
	public void run() {
		for(long i=0; i<1000000000; i++) {} //시간 지연용
		System.out.println(getName() + "우선순위:"+getPriority());
	}
}

public class ThreadProperties {
	public static void main(String[] args) {
		
		//cpu 코어수 
		System.out.println("코어 수:" + Runtime.getRuntime().availableProcessors());
		
		//우선순위 자동 지정
		for(int i=0; i<3; i++) {
			Thread thread = new MyThread();
			thread.start();
		}
		
		try {Thread.sleep(1000);} catch(InterruptedException e) {}
		
		//우선순위 직접 지정
		for(int i=0; i<10; i++) {
			Thread thread = new MyThread();
			thread.setName(i+"번째 쓰레드");
			if(i==9) thread.setPriority(10); //가장 마지막에 실행된 쓰레드 객체에 가장 높은 우선순위 부여 
			thread.start();
		}
	}
}

 

5. 쓰레드의 데몬 설정

 

 - 일반적으로 쓰레드 객체를 실행하면 다른 쓰레드의 종료 여부와 관계없이 자신의 쓰레드가 종료될 때까지 계속 실행

 - 해당 쓰레드를 생성해 실행한 주 쓰레드를 포함해 다른 쓰레드가 종료되면 남아있는 작업이 있다 하더라도 종료 해야 하는 경우 

 ex) 문서 편집 프로그램 자체가 종료되면 자동 저장 쓰레드는 더이상 동작할 필요 없음

 

 - 데몬 쓰레드(daemon thread)

  -> 일반 쓰레드가 모두 종료되면 함께 종료되는 쓰레드 

일반 쓰레드 다른 쓰레드 종료 여부와 상관없이 자신의 작업이 종료될 떄까지 계속 수행
데몬 쓰레드  일반 쓰레드(사용자 쓰레드)가 모두 종료되면 작업이 완료되지 않았더라도 함께 종료 

 

-setDeamon()

 -> Thread 클래스의 인스턴스 메서드 

 -> 쓰레드의 데몬설정

 -> 기본값 false

 -> 데몬 설정은 반드시 쓰레드를 실행하기 전, 즉 start() 메서드 호출 전에 설정 해야 함

 -> 일단 쓰레드가 실행되고 나면 데몬 설정은 바꿀 수 없음

void setDeamon(boolean on)

 

-isDaemon()

 -> Thread 클래스의 인스턴스 메서드 

 -> 생성한 객체의 데몬 설정 여부 

boolean isDaemon()

 

- 쓰레드의 데몬 설정 1.일반 쓰레드

 

 -> 3.5초 동안 지속되는 main 쓰레드 내에서 5초 동안 지속하는 MyThread 객체를 생성 및 실행

 -> MyThread는 일반 쓰레드로 정의 

 -> 프로그램이 시작된지 3.5초 후 main 쓰레드가 종료돼도 MyThread는 자신의 실행이 끝날 떄까지 계속 지속

 

package ThreadProperties;

class MyThread extends Thread {
	//Override
	public void run() {
		System.out.println(getName() + ":"+(isDaemon()? "데몬 쓰레드":"일반 쓰레드"));
		for(int i=0; i <6; i++) {
			System.out.println(getName() + ":"+i+"초");
			try {Thread.sleep(1000);} catch(InterruptedException e) {}
		}
	}
}

public class ThreadProperties {
	public static void main(String[] args) {
		
		//일반 쓰레드 
		Thread thread1 = new MyThread();
		thread1.setDaemon(false); //일반 쓰레드로 설정
		thread1.setName("thread1");
		thread1.start();
		
		//3.5초 후 main 쓰레드 종료 
		try {Thread.sleep(3500);} catch(InterruptedException e) {}
		System.out.println("main Thread 종료");
		
	}
}

 

-쓰레드의 데몬 설정 2. 데몬 쓰레드 

  

 -> MyThread 객체를 실행하기 전에 setDaemon(true)로 설정해 데몬 쓰레드로 정의 

 -> MyThread가 아직 실행할 내용이 남아 있는데도 main 쓰레드가 종료되면 함께 종료 

 

package ThreadProperties;

class MyThread extends Thread {
	//Override
	public void run() {
		System.out.println(getName() + ":"+(isDaemon()? "데몬 쓰레드":"일반 쓰레드"));
		for(int i=0; i <6; i++) {
			System.out.println(getName() + ":"+i+"초");
			try {Thread.sleep(1000);} catch(InterruptedException e) {}
		}
	}
}

public class ThreadProperties {
	public static void main(String[] args) {
		
		//데몬 쓰레드 
		Thread thread2 = new MyThread();
		thread2.setDaemon(true); //데몬 쓰레드로 설정
		thread2.setName("thread2");
		thread2.start();
		
		//3.5초 후 main 쓰레드 종료 
		try {Thread.sleep(3500);} catch(InterruptedException e) {}
		System.out.println("main Thread 종료");
		
	}
}

 

- 쓰레드의 데몬 설정 3. 일반쓰레드와 데몬 쓰레드 

 

 -> main 쓰레드에서는 MyThread 객체를 2개 생성해 실행 

 (첫번째 - 일반 쓰레드 , 두번째 - 데몬 쓰레드)

 -> 두번째 쓰레드는 데몬쓰레드인데도 main 쓰레드가 끝난 이후에도 계속 지속 

 -> 데몬쓰레드는 주 쓰레드가 아니라 프로세스 내의 모든 일반 쓰레드가 종료돼야 종료됨

  ( 일반 쓰레드인 thread1이 아직 끝나지 않았기 때문에 지속)

 

package ThreadProperties;

class MyThread extends Thread {
	//Override
	public void run() {
		System.out.println(getName() + ":"+(isDaemon()? "데몬 쓰레드":"일반 쓰레드"));
		for(int i=0; i <6; i++) {
			System.out.println(getName() + ":"+i+"초");
			try {Thread.sleep(1000);} catch(InterruptedException e) {}
		}
	}
}

public class ThreadProperties {
	public static void main(String[] args) {
		
		//일반 쓰레드 
		Thread thread1 = new MyThread();
		thread1.setDaemon(false); //일반 쓰레드로 설정
		thread1.setName("thread1"); 
		thread1.start();
		
		//데몬 쓰레드 
		Thread thread2 = new MyThread();
		thread2.setDaemon(true); //데몬 쓰레드로 설정
		thread2.setName("thread2");
		thread2.start();
		
		//3.5초 후 main 쓰레드 종료 
		try {Thread.sleep(3500);} catch(InterruptedException e) {}
		System.out.println("main Thread 종료");
		
	}
}

'Java' 카테고리의 다른 글

15 - 4 장 쓰레드의 동기화  (0) 2023.06.14
15 -2장 쓰레드의 생성 및 실행  (0) 2023.06.14
15 - 1장 프로그램, 프로세스, 쓰레드  (0) 2023.06.13
14 - 4장 사용자 정의 예외 클래스  (0) 2023.06.13
14 - 3장 예외 전가  (0) 2023.06.13