1.Runnable, Thread


쓰레드는 전에 설명했듯이 작업을 병렬적으로 수행할 때에 사용하는데


실제로는 두개가 나란히 작동되는게 아니고 라운드로빈이라는 스케줄링 기법을 사용한다.


라운드로빈을 사용하기에 매번 똑같은 결과를 얻을 수 없고 작업 순서가 매번 다르게 실행된다.


CPU의 계산을 최대한 효율적이고 모든 프로그램에 공평하게 할당하기 위해 만들어낸 여러가지 기법들 중 하나이다.


Java에서는 Runnable인터페이스나 Thread 클래스를 상속 받아 멀티 스레드를 구현할 수 있다.


Runnable의 경우는 run메소드 작업을 정의 한 후 Thread 생성 시 안에 집에 넣는다.


Runnable로 따로 정의하지 않고 Thread의 오버라이드 된 run에 바로 정의를 하여도 문제가 없어 보통은 Thread만 단독으로 자주 쓴다.


익명객체를 사용하여 객체 선언과 동시 메소드를 1회용으로 만들수 있다.


다음 예제를 확인해보자.






package chap10.exam01.runnable;

public class Job implements Runnable {

	@Override
	public void run() {
		for(int i = 0; i < 5; i++) {
			System.out.println("워크 스레드 실행");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
package chap10.exam01.runnable;

public class MainThread {

	// Main Thread를 main에서 발생 시킨다.
	// 굉장히 중요
	public static void main(String[] args) {
		
		// 함께 일해줄 WorkThread 생성(Runnable)
		// 1. work thread가 해야할 일 생성
		Runnable job = new Job();
		// 2. 일 해줄 스레드 생성
		Thread thread = new Thread(job);
		// 3. 일을 시킨다. (무조건 start로 시작함)
		thread.start();
		// 동시 실행 테스트
		for(int i = 0; i < 5; i++) {
			System.out.println("메인 스레드 실행");
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}



익명객체를 이용한 스레드


package chap10.exam01.runnable;

public class AnonyMain {

	public static void main(String[] args) {
		// 스레드 생성(할 일) 과 같이 생성
		// 익명객체, 따로 java파일을 만들 필요가 없음
		Thread thread = new Thread() {			
			@Override
			public void run() {
				for(int i = 0; i < 5; i++) {
					System.out.println("워크 스레드 실행");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		// 스레드 실행
		thread.start();
		
		// 메인에서 실행할 작업
		for(int i = 0; i < 5; i++) {
			System.out.println("메인 스레드 실행");
			try {
				Thread.sleep(400);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

}


'개념 및 코딩 > 08.Thread 스레드' 카테고리의 다른 글

[JAVA]08-07.Thread Pool, Pool Block  (0) 2018.09.06
[JAVA]08-05.Demon Thread  (0) 2018.09.06
[JAVA]08-04.Thread State, Control  (0) 2018.09.06
[JAVA]08-03.Priority, Synchronized  (0) 2018.09.06
[JAVA]08-01.Thread  (0) 2018.09.04

1.Thread


스레드는 작업을 수행하는 단위로 단순하게 cpu의 코어가 2개, 듀얼 코어라면 2개의 작업(스레드)을 동시에 할 수 있다.


지금까지의 작업은 싱글 스레드, 하나의 작업을 돌린것이다.


이 스레드를 이용하면 여러가지의 작업들 동시에, 병렬적으로 처리 할 수 있다.


public static void main(String[] args)가 있는 스레드를 메인 스레드라고 하고


스레드를 추가하여 병렬작업을 하는것을 멀티 스레딩이라고 한다.


멀티 스레딩의 장단점으로는 아래와 같다.


 - 장점


CPU 이용률 향상

효율적인 자원 활용

수행 기능별로 분리하여 코드가 간결해짐

어플리케이션의 응답성 향상


 - 단점


같은 프로세스의 자원을 공유하므로 동기화가 필요

동기화 처리에 관한 이슈 처리 필요(교착상태, 기아상태 등)

CPU환경이나 OS의 스케줄러를 고려해야 함

'개념 및 코딩 > 08.Thread 스레드' 카테고리의 다른 글

[JAVA]08-07.Thread Pool, Pool Block  (0) 2018.09.06
[JAVA]08-05.Demon Thread  (0) 2018.09.06
[JAVA]08-04.Thread State, Control  (0) 2018.09.06
[JAVA]08-03.Priority, Synchronized  (0) 2018.09.06
[JAVA]08-02.Runnable, Thread  (0) 2018.09.04

1.스택(Stack)


스택과 큐는 자료구조를 공부한다면 바로 접할 수 있는 그 스택과 큐다.


스택은 LIFO(Last in First Out)으로 마지막으로 들어온 자료가 처음으로 나온다. 의미 그대로의 자료 구조를 가지고 있다.


수건을 예로 든다면 잘 개어진 수건을 사용한다고 할 때에 수건을 개어서 쌓아서 보관을 한다.


1. 쌓아서 차곡차곡 위에 올려서 보관하고


2. 꺼내 쓸 때에는 맨 위부터 하나씩 빼게 된다.


스택의 자료구조도 이와 같은 느낌이다.


Java에서도 사용 할 수 있게 구현이 되어있다 다음 예를 통해 메소드 활용과 함께 확인해보자



package chap09.exam05.stack;

public class Towel {
	
	private String color;

	public Towel(String color) {
		this.color = color;
	}

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}	

}
package chap09.exam05.stack;

import java.util.Stack;

public class TowelBox {

	public static void main(String[] args) {

		// 수건통
		Stack<Towel> box = new Stack<Towel>();
		
		// 넣기(push)
		box.push(new Towel("red"));
		box.push(new Towel("orange"));
		box.push(new Towel("yellow"));
		box.push(new Towel("green"));
		box.push(new Towel("blue"));
		box.push(new Towel("blush violet"));
		box.push(new Towel("purple"));
		System.out.println(box.size());
		
		// 수건 빼기
		Towel towel = box.pop();
		System.out.println(towel.getColor());
		System.out.println(box.size());
		
		// 타올을 뺀 다음 색상 확인(메소드 체이닝)
		System.out.println(box.pop().getColor());
		System.out.println(box.size());
		
		// 남아있는 수건을 하나씩 뽑아서 모두 색상을 확인
		int number = box.size();
		for(int i = 0; i < number; i++) {
			System.out.println(box.pop().getColor());
			System.out.println(box.size());
		}
		// for문이나 while문 셋 중 두개만 주석(ctrl + /)처리해서
		// 테스트 해보면 같은 결과를 얻을 수 있음
		while(box.size() > 0) {
			// pop은 값을 확인하고 버림
			System.out.println(box.pop().getColor());
			// peek은 값을 확인만 함
//			System.out.println(box.peek().getColor());
			System.out.println(box.size());
		}
		// 향상된 for에서 내부적으로 pop을 사용하지 않고 있음
		for(Towel item:box) {
			System.out.println(item.getColor());
			System.out.println(box.size());
		}
	}

}



2.큐(Queue)


큐는 스택과 마찬가지로 대표적인 자료구조로 FIFO구조로 이루어진다.


First In First Out이고 처음 들어온 자료가 처음부터 나가는것이다.


마찬가지로 예를 든다면


1. 가게에 물건을 사러 1~5번 손님이 번호에 맞춰 순서대로 계산대에 서게 된다면


2. 1번 손님이 먼저 왔으니 먼저 계산하는 구조


이와 같이 큐는 들어온 순서대로 나가는 구조이다.



package chap09.exam06.queue;

public class Job {

	private String command;
	private String to;
	
	public Job(String command, String to) {
		this.command = command;
		this.to = to;
	}
	
	//command와 to의 수정을 허용하지 않으므로 getter만 만듬

	public String getCommand() {
		return command;
	}

	public String getTo() {
		return to;
	}
	

}
package chap09.exam06.queue;

import java.util.LinkedList;
import java.util.Queue;

public class JobList {

	public static void main(String[] args) {
		// Queue 생성 - 내부구조는 링크드 리스트
		Queue<Job> list = new LinkedList<Job>();
		// 값을 넣을 때 offer
		list.offer(new Job("Send SMS", "A"));
		list.offer(new Job("Send Mail", "B"));
		list.offer(new Job("Send SMS", "C"));
		list.offer(new Job("Send Kakao", "D"));
		list.offer(new Job("Send Call", "E"));
		
		// 등록된 해야할 일(누구에게 무얼 하는지)을 모두 확인 하기
		// 값을 뺄 때 poll
		// peek 확인만 할 때
		// size를 통해 크기 확인
		// isEmpty
//		System.out.println(list.isEmpty());
//		System.out.println(list.size());
//		System.out.println(list.poll().getTo() + "의 다음 사람에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.poll().getTo() + "의 다음 사람에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.peek().getTo() + "에게 할 일 : " + list.poll().getCommand());
//		System.out.println(list.size());
//		System.out.println(list.isEmpty());
		
		while(list.size() > 0) {
			System.out.println("남은 작업 개수 : " + list.size());
			Job j = list.poll();
			System.out.println(j.getCommand() + " to " + j.getTo());
		}
	}

}


주석문은 직접 지웠다가 다시 붙였다가 하며 테스트를 해보자(Ctrl+/)

'개념 및 코딩 > 07.Collection Framework' 카테고리의 다른 글

[JAVA]07-04.HashMap, HashTable  (0) 2018.09.04
[JAVA]07-03.Hashset  (0) 2018.09.04
[JAVA]07-02.ArrayList, LinkedList  (0) 2018.09.04
[JAVA]07-01.Collection, Map  (0) 2018.09.04

+ Recent posts