-
자바 -thread(2) [5~8]언어/JAVA 2023. 3. 20. 16:17
1.쓰레드의 우선순위
쓰레드는 우선순위(priority)라는 속성을 가지고 있다. 우선순위에 따라 쓰레드가 얻는 실행시간이 달라진다.
우선순위가 높으면, 더 많은 작업시간을 할당할 수 있다.
-void setPriority(int newPriority) -쓰레드의 우선순위를 지정한 값으로 변경 (기본값 5)
-int getPriority() -스레드의 우선순위를 반환한다.
*JVM은 우선순위를 1~10까지 두고있고, winOS는 32단계의 우선순위를 가지고 있다. 쓰레드는 결론적으로 os의 스케쥴러에 의해 영향을 받으므로, 우리가 jvm을 통해 설정하는 우선순위는 희망사항일 뿐 강제될 순 없다.
public class ThreadEX1 { //static long startTime =0; public static void main(String[] args) { Threadex th = new Threadex(); Threadex2 th2 = new Threadex2(); th.setPriority(7); th.start(); th2.start(); } } class Threadex extends Thread{ @Override public void run(){ for(int i=0; i<300;i++){ System.out.printf("%s",new String("a")); for(int x=0; x<1000000;x++); } } } class Threadex2 extends Thread{ @Override public void run(){ for(int i=0; i<300;i++){ System.out.printf("%s",new String("b")); for(int x=0; x<1000000;x++); } } }
우선순위를 높여서 a,b를 출력한다. 매번 그런것은 아니지만, b가 많은 작업시간을 먼저 할당받을 때가 있다.
2.쓰레드 그룹
쓰레드 그룹이란 서로 관련된 쓰레드를 그룹으로 다루기 위한 것이다.
-마치 폴더를 생성해서 파일을 관리하듯 쓰레드 또한 그룹을 생성해서 묶어서 관리할 수 있다.
-쓰레드 그룹에 또다른 하위 쓰레드 그룹을 포함 시킬 수 있다.
-모든 쓰레드는 반드시 하나의 그룹에 속해야한다.
-Thread(ThreadGroup group, String name) Thread생성자에서 그룹 미지정시 main 쓰레드 그룹이 default로 설정된다.
(쓰레드 그룹에 쓰레드를 포함시키려면 Thread생성자 이용해야함)
-자신을 생성한 부모쓰레드 그룹과 우선순위를 상속받는다 (ex main에서 start()된 쓰레드는 main쓰레드 그룹,우선순위 5)
*쓰레드는 기본적으로 묶여서 다뤄진다는 점과 쓰레드를 관리할 때 그룹으로 관리할 수 있다는 점을 기억해두자
+ ThreadGroup getThreadGroup() -자신이 속한 쓰레드 그룹 반환
void uncaughtException(Thread t, Throwable e)
자바 어플리케이션이 실행되면, jvm은 main과 system이라는 쓰레드 그룹을 만든다
jvm 운영에 필요한 쓰레드들을 생성해서 이 쓰레드 그룹에 포함시킨다.
-main메서드를 수행하는 main이라는 이름의 쓰레드는 main쓰레드 그룹, 사비지컬렉션을 수행하는 finalizer쓰레드는 system쓰레드 그룹에 속한다.
-우리가 생성하는 모든 쓰레드 그룹은 main 쓰레드 그룹의 하위 쓰레드 그룹이 된다.(미지정시 그냥 main쓰레드 그룹에 포함)
public class ThreadEX1 { //static long startTime =0; public static void main(String[] args) { ThreadGroup main = Thread.currentThread().getThreadGroup(); ThreadGroup grp1 = new ThreadGroup("group1"); //쓰레드 그룹생성 ThreadGroup grp2 = new ThreadGroup("group2"); //폴더만 생성한 격 아직 파일은 없다. ThreadGroup subGrp1 = new ThreadGroup(grp1,"sub1"); //group1의 하위 그룹 생성 grp1.setMaxPriority(3); //group1의 모든 우선순위 3 Runnable r = new Runnable(){ //쓰레드 만들려고 Runnable하나 지정 @Override public void run() { try{ Thread.sleep(1000); }catch (InterruptedException e){} } }; new Thread(grp1,r,"th1").start(); //각 그룹에 쓰레드 추가 후 실행 new Thread(subGrp1,r,"th2").start(); //(그룹,"쓰레드 이름(변수명 말고 그룹내 식별)") new Thread(grp2,r,"th3").start(); //(그룹,runable r, "쓰레드이름") System.out.println(">>List of ThreadGrop: " +main.getName()+",Active Group "+main.activeGroupCount()+", Active Thread " +main.activeCount()); main.list(); } }
3 데몬 쓰레드(daemon thread)
데몬 쓰레드는 다른 일반 쓰레드의 작업을 돕는 보조적인 역할을 수행하는 쓰레드이다.
-일반쓰레드가 모두 종료되면 데몬 쓰레드는 자동 종료된다.
- 가비지컬렉터, 자동저장기능, 화면자동갱신기능 등이 데몬쓰레드의 예이다.
데몬쓰레드 생성
-무한루프와 조건문을 활용하여 run()을 채운다. ->계속 실행 대기상태, 특정조건이 만족되면 작업을 수행하고 다시 대기
-void setDaemon(boolean on)을 이용해서 쓰레드를 데몬쓰레드 혹은 일반쓰레드로 변경한다. setDaemon은 반드시 start()전에 호출 되어야 한다.
*boolean isDaemon() 쓰레드가 데몬인지 아닌지 확인
public class ThreadEX1 implements Runnable { static boolean autosave = false; public static void main(String[] args) { Thread t = new Thread(new ThreadEX1()); t.setDaemon(true); t.start(); for(int i=1; i<=10 ; i++){ try{ Thread.sleep(1000); }catch (InterruptedException e){} System.out.println(i); if(i==5)autosave=true; } System.out.print("프로그램을 종료합니다."); }; @Override public void run() { while(true){ try{ Thread.sleep(3*1000); }catch (InterruptedException e){} if(autosave){ autosave(); } } } public void autosave() { System.out.println("작업파일이 자동저장됨"); } }
public class ThreadEX1 { public static void main(String[] args) throws Exception{ ThreadEx2 t1 = new ThreadEx2("Thread1"); ThreadEx3 t2 = new ThreadEx3("Thread2"); t1.start(); t2.start(); } } class ThreadEx2 extends Thread{ ThreadEx2(String name){ super(name); } public void run(){ try{ sleep(5*1000); }catch (InterruptedException e){} } } class ThreadEx3 extends Thread{ ThreadEx3(String name){ super(name); } public void run(){ Map map = getAllStackTraces(); Iterator it = map.keySet().iterator(); int x=0; while(it.hasNext()){ Object obj = it.next(); Thread t = (Thread)obj; StackTraceElement[] ste = (StackTraceElement[]) (map.get(obj)); System.out.println("["+ ++x+"] name :"+t.getName()+", group :"+t.getThreadGroup().getName() +",daemon: "+t.isDaemon()); //쓰레드 관련내용 출력 for(int i=0; i<ste.length;i++) System.out.println(ste[i]); //element관련내용출력 System.out.println(); } } } //getAllStackTraces() 실행중, 대기상태 , 작업완료x 모든 쓰레드 kv key thread val StackTraceElement[]
4 쓰레드의 실행제어
쓰레드 프로그래밍이 어려운 이유는 동기화와 스케줄링 때문이다.
쓰레드 스케줄링을 잘하려면 쓰레드 상태와 관련된 메서드를 잘 알아야 한다.
4.1 쓰레드 스케쥴링 메서드
각 메서드들은 추후에 자세히 알아볼 것이다.
4.2 쓰레드의 상태
쓰레드의 상태는 다음과 같이 나눌 수 있다.
생성
NEW - 쓰레드가 생성되고 아직 start()가 호출되지 않은 상태
실행대기
RUNNABLE - 실행 중 혹은 실행 가능 상태 -start() ,yield() 쓰레드 순서양보
--일시정지--------------------------------
BLOCKED - 동기화블럭에 의해서 일시정지 상태(LOCK가 풀릴 때까지 기다리는중)
WAITING, TIMED-WAITING - 쓰레드 작업이 종료된 것은 아니지만, 실행가능하지 않은 일시정지 상태. TIMED-WAITING은 일시정지 시간이 지정된 경우이다.
(suspend <-> resume(), nofity()<->wait(), interrupt()<->sleep() + time-out, i/o block, join())
-----------------------------------------------
소멸
TERMINATED - 쓰레드 작업이 종료된 상태이다.
참고자료:
자바의정석 (남궁성 저)
'언어 > JAVA' 카테고리의 다른 글
자바 - Arrays 클래스와 Comparator (0) 2023.03.23 자바 - Thread(4) 동기화 (0) 2023.03.21 자바 - thread(3) 실행제어 메서드 예제 (0) 2023.03.21 자바 - thread(1) 기본특성 (1~4) (0) 2023.03.20 자바 - Generics (0) 2023.03.16