nme.kr

Ch.17 스레드

프로세스와 스레드

package chapter17;

public class ProcessEx {

	public static void main(String[] args) {
		
		try {
			// 메모장 실행
			Process p1 = Runtime.getRuntime().exec("calc.exe");
			// 그림판 실행
			Process p2 = Runtime.getRuntime().exec("mspaint.exe");
			
			p1.waitFor(); // p1 프로세스가 종료될때까지 대기
			p2.destroy(); // p1 프로세스가 종료되면 실행
			
		} catch(Exception e) {
			e.printStackTrace();
		}

	}

}

스레드 생성과 실행

package chapter17;

public class ThreadEx {

	public static void main(String[] args) {
		
		// Thread 상속받는 방법
		ThreadExtend t1 = new ThreadExtend();
		
		// Runnable 구현하는 방법
		Runnable r = new RunnableImple();
		// Thread 생성자의 매개변수로 전달
		Thread t2 = new Thread(r);
		
		t1.start();
		t2.start();

	}

}

class ThreadExtend extends Thread {
	public void run() {
		System.out.println("Thread 상속받는 방법");
		for (int i=0; i<50; i++) {
			System.out.println("ThreadExtend:"+i);
		}
	}
}

class RunnableImple implements Runnable {
	public void run() {
		System.out.println("Runnable 구현하는 방법");
		for (int i=0; i<50; i++) {
			System.out.println("RunnableImple:"+i);
		}
	}
}

package chapter17;

public class ThreadEx2 {

	public static void main(String[] args) {
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("t1 스레드 시작");
				for (int i=0; i<50; i++) {
					System.out.println("t1 : "+i);
				}
			}
		});
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("t2 스레드 시작");
				for (int i=0; i<50; i++) {
					System.out.println("t2 : "+i);
				}
			}
		});
		
		t1.start();
		t2.start();

	}

}

package chapter17;

public class ThreadEx3 {

	public static void main(String[] args) {
		
		Thread t1 = new Thread(() -> {
			System.out.println("t1 스레드 시작");
			for (int i=0; i<50; i++) {
				System.out.println("t1 : "+i);
			}
		});
		
		Thread t2 = new Thread(() -> {
			System.out.println("t2 스레드 시작");
			for (int i=0; i<50; i++) {
				System.out.println("t2 : "+i);
			}
		});
		
		t1.start();
		t2.start();

	}

}

스레드 우선순위

package chapter17;

public class ThreadEx4 {

	public static void main(String[] args) {
		
		Thread t1 = new Thread(() -> {
			System.out.println("t1 스레드 시작");
			for (int i=0; i<50; i++) {
				System.out.println("t1 : "+i);
			}
		});
		
		Thread t2 = new Thread(() -> {
			System.out.println("t2 스레드 시작");
			for (int i=0; i<50; i++) {
				System.out.println("t2 : "+i);
			}
		});
		
		// 우선순위 지정
		t1.setPriority(7);
		t2.setPriority(3);
		
		t1.start();
		t2.start();

	}

}

스레드 상태 제어

package chapter17;

public class ThreadEx7 {

	public static void main(String[] args) {
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i=0; i<10; i++) {
					System.out.println("t1:"+i);
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {}
				}
				System.out.println("스레드 실행 종료");
			}
		});
		
		
		t1.start();

	}

}


package chapter17;

public class ThreadEx5 {

	public static void main(String[] args) {
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					int i=1;
					while (true) {
						System.out.println("t1:"+i);
						// sleep을 넣지 않으면 interrupt되지 않음
						Thread.sleep(1000);
						i++;
					}
				} catch (InterruptedException e) {
					
				}
				System.out.println("스레드 실행 종료");
			}
		});
		
		
		t1.start();
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			
		}
		t1.interrupt();

	}

}


package chapter17;

public class ThreadEx8 {

	public static void main(String[] args) {
		
		Sum t1 = new Sum();
		Sum t2 = new Sum();
		
		t1.start();
		t2.start();
		try {
			t1.join(); // t1 스레드가 종료될때까지 대기
			t2.join(); // t2 스레드가 종료될때까지 대기
		} catch (InterruptedException e) {
			
		}
		System.out.println("두 스레드의 sum 합계 = "+(t1.sum+t2.sum));

	}

}

class Sum extends Thread {
	int sum = 0;
	@Override
	public void run() {
		for (int i=1; i<=100; i++) {
			sum += i;
		}
	}
}

package chapter17;

public class ThreadEx9 {

	public static void main(String[] args) {
		
		YieldThread t1 = new YieldThread();
		YieldThread t2 = new YieldThread();
		
		t1.start();
		t2.start();
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {}
		
		t1.isContinue = false; // t1 양보
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {}
		
		t1.isContinue = true; // t1 다시 실행
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {}
		
		// 스레드 종료
		t1.isBreak = true;
		t2.isBreak = true;

	}

}

class YieldThread extends Thread {
	boolean isBreak = false;
	boolean isContinue = true;
	
	@Override
	public void run() {
		while(!isBreak) {
			if (isContinue) {
				System.out.println(getName()+" 실행 중");
			} 
		}
		System.out.println(getName()+" 종료");
	}
}

스레드 동기화

package chapter17;

public class ThreadEx10 {

	public static void main(String[] args) {
		
		// 게임 객체 생성
		SmartPhoneGame game = new SmartPhoneGame();
		
		// 플레이어1 객체 생성 후 스레드 실행
		Player1 p1 = new Player1();
		p1.setSmartPhoneGame(game);
		p1.start();
		
		// 플레이어2 객체 생성 후 스레드 실행
		Player2 p2 = new Player2();
		p2.setSmartPhoneGame(game);
		p2.start();
		
	}

}

// 스마트폰게임 클래스
class SmartPhoneGame {
	private int level; // 레벨
	
	public int getLevel() {
		return this.level;
	}
	
	
	public synchronized void increaseLevel() {
		while (true) {
			this.level++; // 레벨 1씩 증가
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {}
			// 현재 스레드의 이름과 레벌 출력
			System.out.println(Thread.currentThread().getName()+" Level : " + this.level);
			if (this.level == 5) {
				notifyAll();
				try { 
					wait();
				} catch (InterruptedException e) {}
				break;
			}
			
			
			// 레벨이 10의 배수가 되면 종료
			if (this.level % 10 == 0) break;
		}
	}
	
	
}

// 플레이어1 스레드
class Player1 extends Thread {
	private SmartPhoneGame game;
	
	public void setSmartPhoneGame(SmartPhoneGame game) {
		this.setName("Player1");
		this.game = game;
	}
	
	@Override
	public void run() {
		game.increaseLevel();
	}
}

// 플레이어2 스레드
class Player2 extends Thread {
	private SmartPhoneGame game;
	
	public void setSmartPhoneGame(SmartPhoneGame game) {
		this.setName("Player2");
		this.game = game;
	}
	
	@Override
	public void run() {
		game.increaseLevel();
	}
}

package chapter17;

public class ThreadEx14 {

	public static void main(String[] args) {
		
		// 통장 객체 생성
		Account acc = new Account();
		
		// 엄마스레드 객체 생성
		Mother mother = new Mother(acc);
		// 아들스레드 객체 생성
		Son son = new Son(acc);
				
		
		mother.start();
		son.start();
		
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {}
		
		// 스레드 중지
		son.interrupt();
		mother.interrupt();
		
	}

}

// 통장 클래스
class Account {
	int money;
	synchronized void withdraw() {
		while(money == 0) {
			try {
				wait();
			}catch(InterruptedException e) {
				break;
			}
		}
		notifyAll();
		System.out.println(Thread.currentThread().getName() + money + "원 출금");
		money = 0;
	}
	synchronized void deposit() {
		while(money > 0) {
			try {
				wait();
			} catch(InterruptedException e) {
				break;
			}
		}
		// 랜덤 입금 1~5만원
		money = (int)((Math.random()*5)+1)*10000;
		notifyAll();
		System.out.println();
		System.out.println(Thread.currentThread().getName() + money + "원 입금");
	}
}

// 엄마 스레드
class Mother extends Thread {
	Account account;
	
	Mother(Account account) {
		super("엄마");
		this.account = account;
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				account.deposit();
				sleep((int)(Math.random()*2000));
			} catch (InterruptedException e) {
				break;
			}
		}
	}
}

//아들 스레드
class Son extends Thread {
	Account account;
	
	Son(Account account) {
		super("아들");
		this.account = account;
	}
	
	@Override
	public void run() {
		while(true) {
			try {
				account.withdraw();
				sleep((int)(Math.random()*300));
			} catch (InterruptedException e) {
				break;
			}
		}
	}
}

데몬 스레드

package chapter17;

public class ThreadEx12 {

	public static void main(String[] args) {
		
		// 스레드 객체 생성
		DaemonThread dt1 = new DaemonThread();
		DaemonThread dt2 = new DaemonThread();
		
		// 데몬스레드로 설정
		dt1.setDaemon(true);
		dt2.setDaemon(true);
		
		dt1.start();
		dt2.start();
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {}
		System.out.println("main 종료");
		
	}

}

class DaemonThread extends Thread {
	public void run() {
		while(true) {
			System.out.println(getName());
			try {
				sleep(500);
			} catch (InterruptedException e) {}
		}
	}
}

스레드 그룹

package chapter17;

public class ThreadEx13 {

	public static void main(String[] args) {
		
		// 그룹 객체 생성
		ThreadGroup group = new ThreadGroup("Group1");
		MyThread t1 = new MyThread(group, "First");
		MyThread t2 = new MyThread(group, "Second");
		MyThread t3 = new MyThread(group, "Third");
		
		
		t1.start();
		t2.start();
		t3.start();
		
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {}
		
		// 모든 스레드 중지
		group.interrupt();
		
	}

}

class MyThread extends Thread {
	MyThread(ThreadGroup group, String name) {
		super(group, name);
	}
	
	@Override
	public void run() {
		while(true) {
			System.out.println(getName());
			try {
				sleep(500);
			} catch (InterruptedException e) {
				System.out.println(getName() + " interrupted 발생");
				break;
			}
		}
		System.out.println(getName()+" 종료");
	}
}