KDT/Java

240320 Java - 스레드 2

001cloudid 2024. 3. 20. 18:45
728x90

스레드

싱글 스레드

package test18;

public class Thread1 {

	public static void main(String[] args) {

		//스레드(Thread)
		//하나의 프로세스에서 동시에 기능을 처리하기 위한 목적으로 사용되는 실행 단위
		//하나의 프로세스에는 1개 이상의 스레드가 존재함
		//싱글(메인) 스레드 : 최초 실행 시 메인 스레드가 main() 함수를 실행시킴
		//멀티 스레드 : 하나의 기능을 실행할 수 있는 실행 단위(스레드)가 여러 개인 것을 말함
		//스레드를 사용하는 목적은 '동시 작업 처리'
		
		//JVM이 운영체제 역할을 함(CPU 역할)
		//자바는 프로세스가 존재하지 않고 스레드만 존재
		//JVM에 의해 스케쥴되는 실행 단위 코드 블록. 하나의 프로세스(응용 프로그래밍) 내에서 여러 가지 작업을 동시에 수행 할 수 있게 하는 것
		
		//스레드를 만드는 2가지 방법
		//1) Thread 클래스를 상속받아 Thread 작성
		//	 Thread 클래스를 상속받아 run() 메소드를 오버라이딩 함으로써 구현 하는 방식
		
		//2) java.lang.Runnable 인터페이스를 구현하여 Thread 작성 
		//	 Runnable 인터페이스를 구현함으로써 Thread를 사용하는 방식. main에서 Thread 생성 정보로 구현한 클래스의 객체를 넘겨줌으로써 객체를 생성하는 방식
		
		//메소드
		//start() run()메소드 호출
		//run() 스레드가 실행할 부분에 기술하는 스레드 코드로 오버라이딩하여 스레드 코드를 작성. 메소드가 종료하면 스레드도 종료됨
		
		//1. 싱글 스래드(main 함수 내에서 처리되는 주 스레드 1개뿐인 것이 기본)
		for(int i=0;i<300;i++) {
			System.out.println("$ "+(i+1));
		}
		
		for(int i=0;i<300;i++) {
			System.out.println("* "+(i+1));
		}
		System.out.println();
		System.out.println("main 스레드 종료");
		
		
	}

}

 

멀티 스레드

package test18;

//첫번째 스레드 : Thread 클래스를 상속받아서 구현 run() 메소드 오버라이드
class One extends Thread{

	@Override
	public void run() {

		for(int i=0;i<300;i++) {
		System.out.println("$ "+(i+1));
		}
		System.out.println("One 스레드 종료");
	}
}

//두번째 스레드 : Runnable 인터페이스 구현 run()메소드 오버라이드
class Two implements Runnable{

	@Override
	public void run() {
		
		for(int i=0;i<300;i++) {
			System.out.println("* "+(i+1));
		}
		System.out.println("Two 스레드 종료");
	}
}


public class Thread2{
	
	public static void main(String[] args) {

		//멀티 스레드 : 수행할 여러 개의 작업 단위의 코드를 블록으로 작성하고 수행
		// -> run() 메소드 내에 수행할 동작 코드를 작성(오버라이드)
		
		//첫번째 스레드
		One t1 = new One(); //Thread 클래스의 멤버를 사용하여 스레드 처리 할 수 있음
		t1.start(); //run()메소드 내의 코드를 수행시킴
		
		//두번째 스레드
		//인터페이스 변수명 = new 구현클래스();
		Runnable t2 = new Two();
		Thread thread = new Thread(t2); //Runnable 인터페이스 내의 run()메소드를 수행시킬 Thread 클래스의 멤버들을 사용하기 위해 Thread 클래스의 생성자에 인터페이스 변수명을 대입
		thread.start();
		
		System.out.println("main 스레드 종료");
		
		
		//순서대로 처리 되는 것이 아니라 동시에 처리됨
	}

}

 

싱글 스레드와 멀티 스레드 비교

src내의 module-info.java

/**
 * 
 */
/**
 * 
 */
module java_basic {
	requires java.desktop;
}

 

package test18;

import javax.swing.JOptionPane;

public class Thread3 {

	public static void main(String[] args) {

		//싱글 스레드와 멀티 스레드 비교
		
		//1. 싱글 스레드 : 하나의 스레드의 수행이 끝나야만 다음 스레드를 수행 할 수 있음
		//Dialog 박스로 데이터값 입력받기
		String in = JOptionPane.showInputDialog("값을 입력");
		System.out.println(in);
		
		//sleep() 메소드 : 현재 스레드를 지정된 시간 동안 멤추게 함
		for(int i=10;i>0;i--) {
			System.out.println(i);
		
		
		try {
			Thread.sleep(1000); //1초 : 1000으로 지정(1/1000 초로 시간 지정이 되어 있음)
		} catch (InterruptedException e) {
				e.printStackTrace();
		}
		
		}
		
		System.out.println("메인 스레드 종료");
		
	}

}

 

package test18;

import javax.swing.JOptionPane;

class Three extends Thread{

	@Override
	public void run() {
		
		for(int i=10; i>0; i--) {
			System.out.println(i);
	
		try {	
		Thread.sleep(1000);
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		}
		System.out.println("Three 스레드 종료");
	}
}

public class Thread4 {

	public static void main(String[] args) {

		//싱글 스레드와 멀티 스레드 비교
		
		//2. 멀티 스레드 : 여러 개의 (경량)스레드를 생성시켜 동시에 병렬 처리하도록 만듦
		//메인 스레드와 Three 스레드 동시 작업
		
		//Three 스레드
		Three three = new Three();
		three.start();
//		Thread thread3 = new Thread(three);
//		thread3.start();
		
		//메인 스레드(주 스레드)
		String in = JOptionPane.showInputDialog("값을 입력");
		System.out.println(in);
		
		System.out.println("메인 스레드 종료");
		
	}

}

 

스레드 우선 순위

  • 작업 중요도에 따라 특정 스레드가 더 많은 작업 시간을 갖게 할 수 있음
  • 우선 순위가 높은 스레드를 먼저 실행한 다음 낮은 스레드를 실행
  • 1~10까지 숫자 번호로 지정할 수 있음
  • 우선 순위의 기본값은 5
  • SetPriority 메소드를 이용하여 변경
  • getPriority 메소드를 이용하여 우선 순위값을 조회할 수 있음
package test18;

class A extends Thread{

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("!" + (i+1));
		}
		System.out.println("A 스레드 종료");
	}
}

class B implements Runnable{

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("@" + (i+1));
		}
		System.out.println("B 스레드 종료");
	}
}


public class Thread5 {

	public static void main(String[] args) {
		
		//Thread 클래스를 상속받았을 때
		A a = new A();
		Thread threadA = new Thread(a,"A 스레드");
		
		//Runnable 인터페이스를 구현했을 때
		Runnable b = new B();
		Thread threadB = new Thread(b,"B 스레드");
		
		System.out.println("Thread 이름 : " + Thread.currentThread().getName());
		System.out.println("Thread ID : " + Thread.currentThread().getId());
		System.out.println("Thread 우선순위 : " + Thread.currentThread().getPriority());
		System.out.println("Thread 인터럽트 : " + Thread.currentThread().isInterrupted());
		System.out.println("=================================");
		
		System.out.println("Tread 이름 : " + threadA.getName());
		System.out.println("Tread ID : " + threadA.getId());
		System.out.println("Tread 우선순위 : " + threadA.getPriority());
		System.out.println("Tread 인터럽트 : " + threadA.isInterrupted());
		System.out.println("=================================");
		
		System.out.println("Tread 이름 : " + threadB.getName());
		System.out.println("Tread ID : " + threadB.getId());
		System.out.println("Tread 우선순위 : " + threadB.getPriority());
		System.out.println("Tread 인터럽트 : " + threadB.isInterrupted());
		System.out.println("=================================");
		
		//스레드 우선 순위 지정
		//작업 중요도에 따라 특정 스레드가 더 많은 작업 시간을 갖게 할 수 있음
		//우선 순위가 높은 스레드를 먼저 실행한 다음 낮은 스레드를 실행
		//1(최소 우선 순위)~10(최대 우선 순위)까지 숫자 번호로 지정할 수 있음
		//우선 순위의 기본값은 5
		//SetPriority 메소드를 이용하여 변경
		//getPriority 메소드를 이용하여 우선 순위값을 조회할 수 있음
		System.out.println("우선 순위 지정");
		threadA.setPriority(1);
		threadB.setPriority(8);
		System.out.println("Tread 우선순위 : " + threadA.getPriority());
		System.out.println("Tread 우선순위 : " + threadB.getPriority());
		System.out.println("=================================");
		
		threadA.start();
		threadB.start();
		System.out.println("메인 스레드 종료");
		
	}
}

 

yield()

package test18;

class C implements Runnable {

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("#" + (i+1));
			//yield() 메소드를 실행한 스레드는 대기 상태가 되고, 우선 순위가 동일하거나 우선순위가 높은 다른 스레드가 실행되도록 함
			Thread.yield();
		}
		System.out.println("C 스레드 종료");
		
		
	}
	
}

class D implements Runnable{

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("$" + (i+1));
		}
		System.out.println("D 스레드 종료");
		
	}
	
}

public class Thread6 {

	public static void main(String[] args) {

		//스레드 양보 : 자신에게 할당된 수행 시간을 다음 차례의 스레드에게 양보
		Thread threadC = new Thread(new C(),"C 스레드");
		Thread threadD = new Thread(new D(),"D 스레드");
		
		threadC.start();
		threadD.start();
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("메인 스레드 종료");
		
		
	}

}

 

join()

  • 지정된 시간 동안 특정 스레드를 기다리게 하는 기능
  • 다른 스레드가 작업하는 것ㅇ들 끝내야만 현재 스레드가 작업할 수 있도록 하는 기능
  • 예외 처리를 해줘야함
package test18;

class E implements Runnable{

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("%" + (i+1));
		}
		System.out.println("E 스레드 종료");
	}
	
}

class F implements Runnable{

	@Override
	public void run() {
		for(int i=0; i<300; i++) {
			System.out.println("^" + (i+1));
		}
		System.out.println("F 스레드 종료");
	}
	
}

public class Thread7 {

	public static void main(String[] args) throws InterruptedException {
		//join() : 다른 스레드의 실행이 완료될 떄까지 기다림
		Thread threadE = new Thread(new E(),"E 스레드");
		Thread threadF = new Thread(new F(),"F 스레드");
		
		threadE.start();
		threadE.join();
		threadF.start();
		threadF.join();
		
		
		//메인 스레드 수행
		for(int i=0; i<10; i++) {
			System.out.println("&" + (i+1));
		}
		System.out.println("메인 스레드 종료");
	}

}

 

package test18;

class X implements Runnable{

	@Override
	public void run() {
		for(int i = 0 ; i <=10; i++) {
			int total = 0;
			total+= i;
			System.out.println("X 합계 : " + total);
		}
		System.out.println("X 스레드 종료");
	}
	
}

class Y implements Runnable{

	@Override
	public void run() {
		int total = 0;
		for(int i = 0 ; i <=10; i++) {
			total+= i;
			System.out.println("Y 합계 : " + total);
		}
		System.out.println("Y 스레드 종료");
		
	}
	
}

public class Thread8 {

	public static void main(String[] args) throws InterruptedException {

		Thread threadX = new Thread(new X(),"E 스레드");
		Thread threadY = new Thread(new Y(),"F 스레드");
		
		threadX.start();
		threadX.join();
		
		threadY.start();
		threadY.join();
		
		
	}

}

 

728x90

'KDT > Java' 카테고리의 다른 글

240325 Java - 제네릭 1  (0) 2024.03.25
240321 Java - 스레드 3  (0) 2024.03.21
240318 Java - 스트림 3, 스레드 1  (0) 2024.03.18
240314 Java - 람다식 2, 스트림 1  (0) 2024.03.14
240313 Java - 람다식  (0) 2024.03.13