romworld

Thread 본문

JAVA/개념정리

Thread

inderrom 2022. 10. 31. 01:08
package kr.or.ddit.basic;

public class ThreadTest01 {

	public static void main(String[] args) {
		// 싱글 쓰레드 프로그램
		for(int i=1; i<=200; i++) {
			System.out.print("*");
		}
		System.out.println();
		System.out.println();
		
		for(int j=1; j<=200; j++) {
			System.out.print("$");
		}
	}
}

 


package kr.or.ddit.basic;

public class ThreadTest02 {

	public static void main(String[] args) {
		// 멀티 쓰레드 프로그램
		
		// Thread를 사용하는 방법
		
		// 방법1
		// Thread클래스를 상속한 class를 작성한 후 이 class의  인스턴스를 생성한 후(객체 생성)
		// 그리고 생성된 이 인스턴스의 start()메서드를 호출해서 실행한다.
		
		//run()으로 호출하게 되면 싱글 스레드처럼 나옴 (의미가 없음)
		MyThread1 th1 = new MyThread1();
		th1.start();
		//th1.run();
		
		//방법2
		// Runnable 인터페이스를 구현한 class를 작성한 후 이 class의 인스턴스를 생성한다.
		// 생성된 인스턴스를 Thread객체를 생성할 때 생성자의 인수값으로 넣어 주고 생성한다.
		// 이 때 생성된 Thread객체의 인스턴스 start()메서드를 호출해서 실행한다.
		MyThread2 r = new MyThread2();
		Thread th2 = new Thread(r);
		th2.start();
		//th2.run();
		
		
		//Runnable r2 = new Runnable(); // 인터페이스 안에는 실행코드가 없으니까 인터페이스 가지고 직접 객체 생성 못함
		
		// 방법 2-1
		// 이렇게 하면 인터페이스를 인스턴스화 할 수 있음
		// 익명구현체
		Runnable r2 = new Runnable() {
			@Override
			public void run() {
				for (int i = 1; i <= 200; i++) {
					System.out.print("@");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO: handle exception
					}
				}
			}
		};

		Thread th3 = new Thread(r2);
		th3.start();
		
		System.out.println("main메스드 끝...");
		// 스레드가 제어권을 받는다고 해도
		// 스레드가 실행을 안할수도 있어서 syso가 먼저 나옴
	}

}

// 방법1
class MyThread1 extends Thread{
	
	// 쓰레드에서 처리할 내용은 run()메서드를 재정의해서 작성한다.
	@Override
	public void run() {
		// 이 run()메서드에서 작성한 명령이 쓰레드가 처리할 명령이 된다.
		// 이 run()메서드의 실행이 끝나면 해당 쓰레드도 종료가 된다.
		for(int i=1; i<=200; i++) {
			System.out.print("*");
			try {
				// Thread.sleep(시간) ==> 주어진'시간'동안 작업을 잠시 멈춘다.
				//				'시간'은 밀리세컨드 단위를 사용한다.(즉, 1000은 1초를 의미)
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
	}
}

// 방법2
 class MyThread2 implements Runnable{
	 @Override
	public void run() {
	 for(int i=1; i<=200; i++) {
		System.out.print("$");
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		}
	}
 }

package kr.or.ddit.basic;

public class ThreadTest03 {

	public static void main(String[] args) {
		// 쓰레드가 처리되는 시간을 체크해 보자...
		Thread th = new Thread(new MyRunner());
		
		// 1970년 1월 1일 0시 0분 0초(표준시간)로 부터 경과한 시간을 밀리세컨드 (1/1000초) 단위로 반환한다.
		long startTime = System.currentTimeMillis();
		
		th.start();
		
		try {
			th.join();   // 현재 위치에서 대상이 되는 쓰레드(현재는 변수 th를 말한다)가 끝날 때까지 기다린다.
			
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("경과 시간 :" + (endTime - startTime));
	}

}

class MyRunner implements Runnable{

	@Override
	public void run() {
		long sum =0L;
		for(long i =1L; i<=1_000_000_000L;i++) {
			sum += i;
		}
		System.out.println("합계: " + sum);
	}
}

package kr.or.ddit.basic;
/*
	1~20억까지의 합계를 구하는 프로그램을 하나의 쓰레드가 단독으로 처리할 때와
	여러개의 쓰레드가 협력해서 처리할 때의 경과시간을 비교해 보자.
 */
public class ThreadTest04 {

	public static void main(String[] args) {
		// 단독으로 처리하는 쓰레드 생성
		SumThread sm = new SumThread(1L, 2_000_000_000L);
		
		// 여러개의 쓰레드가 협력해서 처리할 쓰레드 생성 -- 비효율적임
		/*
		SumThread smTemp1 = new SumThread(           1L,   500_000_000L);
		SumThread smTemp2 = new SumThread( 500_000_001L, 1_000_000_000L);
		SumThread smTemp3 = new SumThread(1_000_000_00L, 1_500_000_000L);
		SumThread smTemp4 = new SumThread(1_500_000_00L, 2_000_000_000L);
		*/
		
		// 그래서 배열로 넣어서 하기
		
		SumThread[] sumThArr = new SumThread[] {
			    new SumThread(            1L,   500_000_000L), 
			    new SumThread(  500_000_001L, 1_000_000_000L), 
			    new SumThread(1_000_000_001L, 1_500_000_000L), 
			    new SumThread(1_500_000_001L, 2_000_000_000L)
		};
		
		// 단독으로 처리하기
		long startTime = System.currentTimeMillis();
		sm.start();
		try {
			sm.join();
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		long endTime = System.currentTimeMillis();
		
		System.out.println("단독으로 처리했을 때 경과 시간 : " + (endTime - startTime));
		System.out.println();
		System.out.println("-------------------------------------------------------------");
		
		//여러 쓰레드가 협력해서 처리하는 경우
		startTime = System.currentTimeMillis();
		
		for(SumThread sth : sumThArr) {
			sth.start();
		}
		
		for(SumThread sth : sumThArr) {
			try {
				sth.join();
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		
		endTime = System.currentTimeMillis();
		
		System.out.println("여러 쓰레드가 협력해서 처리한 경과 시간 : " + (endTime - startTime));
		
	}

}
// 시작값 ~ 종료값까지의 합계를 구하는 클래스 작성
class SumThread extends Thread{
	private long startValue;
	private long endValue;
	public SumThread(long startValue, long endValue) {
		super();
		this.startValue = startValue;
		this.endValue = endValue;
	}
	
	@Override
	public void run() {
		long sum = 0L;
		
		for(long i = startValue; i<=endValue;i++) {
			sum += i;
		}
		System.out.println(startValue +"부터" + endValue + "까지의 합계 : " + sum);
	}
}

package kr.or.ddit.basic;

import javax.swing.JOptionPane;

public class ThreadTest05 {

	public static void main(String[] args) {
		// 사용자로부터 데이터 입력 받기
		String str = JOptionPane.showInputDialog("아무거나 입력하세요.");
		System.out.println("입력값 : " + str); // 취소 esc 누르면 null 값 , 아무것도 안 치고 엔터 누르면 공백 출력
	
	
		
		
		for(int i =10; i>0; i--) {
			System.out.println(i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
	}
}

package kr.or.ddit.basic;

import javax.swing.JOptionPane;

public class ThreadTest06 {

	public static void main(String[] args) {
		
		Thread th1 = new DataInput();
		Thread th2 = new CountDown();
		
		th1.start();
		th2.start();
		
	}
}
// 데이터를 입력하는 쓰레드
class DataInput extends Thread{
	// 입력 여부를 확인하기 위한 변수 선언 ==> 쓰레드에서 공통으로 사용할 변수
	public static boolean inputCheck = false;

	@Override
	public void run() {
		String str = JOptionPane.showInputDialog("아무거나 입력하세요.");
		
		inputCheck = true;	// 입력이 완료되면 inputCheck변수값을 true로 변경한다.
		
		System.out.println("입력한 값 : " + str);
	}
}
// 카운트 다운을 처리하는 쓰레드
class CountDown extends Thread{
	@Override
	public void run() {
		for(int i =10; i>0; i--) {
			
			//입력이 완료되었는지 여부를 검사해서 입력이 완료되면 쓰레드를 종료시킨다.
			if(DataInput.inputCheck==true) {
				return; // run()메서드가 종료되면 쓰레드도 종료된다.
			}
			
			System.out.println(i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		System.out.println("10초가 지났습니다. 프로그램을 종료합니다..");
		System.exit(0);
	}
}

package kr.or.ddit.basic;

//데몬 쓰레드 연습 ==> 자동 저장하는 쓰레드

public class ThreadTest08 {

	public static void main(String[] args) {
		AutoSaveThread auto = new AutoSaveThread();
		
		System.out.println("데몬 설정 전 : " + auto.isDaemon());
		
		//데몬 쓰레드로 설정하기 ==> 반드시 start()메서드 호출 전에 설정해야 한다.
		auto.setDaemon(true);

		System.out.println("데몬 설정 후 : " + auto.isDaemon());
		
		auto.start();
		try {
			for(int i =1; i<=20; i++) {
				System.out.println(i);
				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			// TODO: handle exception
		}
		
		System.out.println("main 쓰레드 종료...");
	}
}

// 자동 저장하는 쓰레드 클래스 작성
class AutoSaveThread extends Thread{
	// 작업 내용을 저장하는 메서드
	public void save() {
		System.out.println("작업 내용을 저장합니다...");
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
			save();
		}
	}
}

package kr.or.ddit.basic;


// 3개의 쓰레드가 각각 알파벳 A ~ Z까지 출력하는데
// 출력을 끝낸 순서대로 결과를 나타내는 프로그램을 작성해 보자.

public class ThreadTest09 {

	public static void main(String[] args) {
		DisplayCharacter[] threadArr = new DisplayCharacter[] {
				new DisplayCharacter("홍길동"),
				new DisplayCharacter("이순신"),
				new DisplayCharacter("강감찬")
		};
		
		for(DisplayCharacter dc : threadArr) {
			dc.start();
		}
		
		for(DisplayCharacter dc : threadArr) {
			try {
				dc.join();
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		}
		System.out.println();
		System.out.println("경기 결과...");
		System.out.println("순 위:" + DisplayCharacter.ranking);
	}

}

// A ~ Z까지 출력하는 쓰레드 
class DisplayCharacter extends Thread{
	public static String ranking = "";
	private String name;
	
	// 생성자
	public DisplayCharacter(String name) {
		this.name = name;
	}
	
	@Override
	public void run() {
		for(char c = 'A'; c<='Z'; c++) {
			System.out.println(name + "의 출력 문자 : " + c);
			try {
				// 난수를 이용하여 일시 정지 시킨다.
				Thread.sleep((int)(Math.random() * 500));
			} catch (InterruptedException e) {
				// TODO: handle exception
			}
		} // for문 끝...
		System.out.println(name + "출력 끝~~~~");
		
		// 출력을 끝낸 순서대로 이름을 배치한다.
		ranking += name + " ";
	}
}

'JAVA > 개념정리' 카테고리의 다른 글

Thread 2  (0) 2022.11.27
Thread 경마 프로그램  (0) 2022.11.27
Generic  (0) 2022.10.31
enum  (1) 2022.10.31
Args  (0) 2022.10.28
Comments