JAVA

[java] 비동기식 스레드 개념, 상태, 그룹, 테스트 코드- 개발자 배찌

개발자 배찌 2022. 12. 16. 19:47
728x90

오늘은 즐거운 불금.

예전부터 들어보고 싶었던 뉴렉처 스레드 강의를

멤버쉽 가입하여 오늘부터 듣게되었다.

 

스레드 개념 정리!!

 

비동기식 스레드 테스트코드 (  스레드 동작과정 / 상태확인 )

	/**
	 * 비동기식 스레드 테스트
	 */
	@RequestMapping(value="ansyncThreadTest.do", method= {RequestMethod.GET, RequestMethod.POST})
	public ModelAndView ansyncThreadTest(HttpServletRequest request) {
		ModelAndView mv = new ModelAndView();
		mv.setViewName("/ansyncThreadTestPag");
		
		//메인스레드
		Thread th = Thread.currentThread();
		th.setName("Main"); //메인스레드의 name을 지정. 생략하면 default로 main
		//print();
		
		Runnable subMain = new Runnable() {
			@Override
			public void run() {
				//메인스레드 상태 확인 : RUNNABLE
				System.out.printf("%s : %s\n", th.getName(), th.getState());
				print();
				//메인스레드 상태 확인 : WAITING.. th1.join()때문에 서브스레드가 끝날 때 까지 기다림
				System.out.printf("%s : %s\n", th.getName(), th.getState());
			}
		};
		
		//스레드 그룹핑
		ThreadGroup thGroup = new ThreadGroup("print main group");
		ThreadGroup thGroup1 = new ThreadGroup(thGroup, "print sub group1");
		ThreadGroup thGroup2 = new ThreadGroup(thGroup, "print sub group2");
		
		
		//서브스레드 생성
		Thread th1 = new Thread(thGroup1,subMain);   
		//스레드를 식별하기 위해 name 지정
		th1.setName("sub1");  
		
		Thread th2 = new Thread(thGroup1,subMain);   
		th2.setName("sub2");
		//th2 우선순위를 가장 낮게 설정
		//th2.setPriority(Thread.MIN_PRIORITY);
		
		//th2를 daemon으로 설정. 다른 스레드들이 끝나면 얘도 강제로 끝나버림
		//th2.setDaemon(true);
		
		Thread th3 = new Thread(thGroup1,subMain);
		th3.setName("sub3");
		Thread th4 = new Thread(thGroup2,subMain);
		th4.setName("sub4");
		Thread th5 = new Thread(thGroup2,subMain);
		th5.setName("sub5");
		Thread th6 = new Thread(thGroup2,subMain);
		th6.setName("sub6");
		
		//th1 스레드 상태 확인 : NEW
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		
		th1.start();
		th2.start();
		th3.start();
		th4.start();
		th5.start();
		th6.start();
		
		
		//th1 스레드 상태 확인 : RUNNABLE
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		//th1 스레드 상태 확인 : RUNNABLE
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		//th1 스레드 상태 확인 : RUNNABLE
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		//th1 스레드 상태 확인 : TIMED_WAITING.. sleep걸림
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		
		
		
		//th1 스레드 상태 확인 : TERMINATED.. th1 스레드 종료
		//현재 메인스레드가 끝나기 전에, 서브스레드가 종료가 된 상태임. 
		//만약 메인스레드보다 서브스레드가 더 늦게 종료되면?
		System.out.printf("%s : %s\n", th1.getName(), th1.getState());
		
		if(th1.isAlive()) {
			try {
				th1.join(2000);  //나(메인)는 th1을 2초만 기다릴거야.
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			th1.interrupt();
		}
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		thGroup.list();
		//thGroup.interrupt();
		thGroup1.interrupt();
		
		System.out.println("==============Main Exit ===========");
		return mv;
	}
	
	private static void print() {
		
		Thread th = Thread.currentThread();
		
		for(int i=0; i<1000000000; i++) {
			try {
				Thread.sleep(2000000000);
			} catch (InterruptedException e) {
				//thread.sleep(2000000000)때문에 기다리느라 아래 interrupted를 인식을 못하는경우 에는
				//exception이 탄다.
				System.out.println("으악! 누가 날 깨운거야?");
			}
			
			//메인메소드에 요청된 interrupt 확인
			if (th.isInterrupted()) {
				System.out.println("-------- Th Interrupted-----------");
				return;  //있으면 return. 끝내버리기
			}
			
			if(th.getName().equals("Main"))
				System.out.printf("<%s[%d] : %d>\n", th.getName(), th.getId(), i+1 );
			else
				System.out.printf("%s[%d] : %d\n", th.getName(), th.getId(), i+1 );
			 
		}
			
	}