1) 제네릭(1)
1 제네릭,람다식
개요
클래스/인터페이스/메소드를 정의할때 타입을 파라미터로 사용할수 있도록 한다.
Casting제거로 프로그램 실행시 타입변환에 소요되는 시간이 없어서 성능이 향상되며, 컴파일
시 강한 타입체크가 가능해서 실행에러보다 컴파일시 에러를 지향한다.
제네릭타입
( class<T>,
interface<T> )
타입을 파라미터로 갖는 클래스/인터페이스를 말함.
public class ClassA<T>{;}
public interface InterfaceB<T> {;}
멀티타입파라미터
(class<K,V,…>,
interface<K,V,…>)
public class Projuct<T,M>{
private T kind;
private M model;
}
제네릭 메소드
(<T,R> R method(T t))
매개타입과 리턴타입으로 파라미터를 갖는 메소드.
선언 : Public <T> Box<T> boxing<T t>{;}
호출 : Box<Integer> box = <Integer>boxing(100);
4.
2) 제네릭(2)
1 제네릭,람다식
제한된
타입 파라미터
(<T extends
최상위타입>)
타입파라미터에 구체적타입을 제한할필요가 있을때 사용.(아래의 경우 Number타입 또는 하위
[Byte/Short/Integer/Long/Double]의 인스턴스만 매개값으로 가져야함.)
public <T extends Number>
int compare(T t1, T t2){;}
와일드카드타입
(<?>,<? extends …>,
<? super …>)
?를 와일드카드라고 부름. 제네릭타입을 매개값이나 리턴타입으로 사용시, 구체적 타입대신
와일드카드를 제네릭타입<?>/제네릭타입<? extends 상위타입>/제네릭타입
<? super 하위타입>으로 사용할 수 있음.
제네릭타입<?>- 타입파라미터를 대치하는 구체적 타입으로 모든 클래스가 올 수 있음.
제네릭타입<? extends 상위타입>-타입 파라미터를 대치하는 구체적 타입으로 상위 타입이나
하위 타입만 올 수 있음.
제네릭타입<? super 하위타입>- 타입 파라미터를 대치하는 구체적 타입으로 하위타입이나 상
위타입이 올 수 있음.
5.
3) 람다식[Lamda Expression](1)
1제네릭, 람다식
제한된
타입 파라미터
(<T extends
최상위타입>)
타입파라미터에 구체적타입을 제한할필요가 있을때 사용.(아래의 경우 Number타입 또는 하위
[Byte/Short/Integer/Long/Double]의 인스턴스만 매개값으로 가져야함.)
public <T extends Number>
int compare(T t1, T t2){;}
와일드카드타입
(<?>,<? extends …>,
<? super …>)
?를 와일드카드라고 부름. 제네릭타입을 매개값이나 리턴타입으로 사용시, 구체적 타입대신
와일드카드를 제네릭타입<?>/제네릭타입<? extends 상위타입>/제네릭타입
<? super 하위타입>으로 사용할 수 있음.
제네릭타입<?>- 타입파라미터를 대치하는 구체적 타입으로 모든 클래스가 올 수 있음.
제네릭타입<? extends 상위타입>-타입 파라미터를 대치하는 구체적 타입으로 상위 타입이나
하위 타입만 올 수 있음.
제네릭타입<? super 하위타입>- 타입 파라미터를 대치하는 구체적 타입으로 하위타입이나 상
위타입이 올 수 있음.
6.
4) 람다식[Lamda Expression](2)
1제네릭, 람다식
개요
병렬처리/이벤트지향프로그래밍에 적합한 함수적 프로그래밍을 위해 람다식을 지원.
익명함수를 생성하기 위한 식.
특징 자바코드간결화,컬렉션요소를 필터링/매핑해서 원하는 결과를 쉽게 집계할 수있음.
동작방식 람다식->매개변수를가진코드블럭->익명구현객체
문법
(int a) -> {System.out.println(a);}//int생략가능
(x,y)->x+y;
타겟타입
람다식은 메소드 선언과 메소드를 가진 객체 생성.
형태 ) 인터페이스 변수 = 람다식;
함수적 인터페이스
(@Functional
Interface)
람다식이 하나이상의 메소드를 정의하기 때무에 2개 이상의 추상메소드가 선언된 인터페이스
는 람다식을 이용해 구현객체를 생성할 수 없음.
추상메소드가 1개만 선언된 인터페이스가 람다식의 타겟 타입이 될 수 있으며, 이를 함수적 인
터페이스라 부름.
함수적 인터페이스 작성시 @FunctionalInterface 어노테이션을 붙여서 두개이상의 추상메
소드가 선언되지 않도록 체킹함.
7.
5) 람다식[Lamda Expression](3)
1제네릭, 람다식
매개변수와
반환값이 없는
람다식
@FunctionalInterface
public interface MyFI{pulbic void method();}
위처럼 매개변수와 반환값이 없는 추상메소드를 가진 함수적 인터페이스를 가진 람다식은 경우
아래와 같이 작성해야함.
MyFI fi=()->{;}
매개변수가 있는
람다식
@FunctionalInterface
public interface MyFI{pulbic void method(int a);}
위처럼 매개변수만있는 추상메소드를 가진 함수적
인터페이스를 가진 람다식은 경우 아래와 같이 작성해야함.
MyFI fi=(x)->{;} 또는 x->{;}
반환값이 있는
람다식
@FunctionalInterface
public interface MyFI{pulbic int method(int a);}
위처럼 매개변수와 반환값이 있는 추상메소드를
가진 함수적 인터페이스를 가진 람다식은 경우
아래와 같이 작성해야함.
MyFI fi=(x,y)->{ ; return value;}
클래스멤버와
로컬변수사용
람다식 실행블록에서는 클래스 멤버/로컬변수를 사용할 수 있음.
클래스 멤버는 사용에 제약이 없으나 로컬변수는 제약이 있음
8.
6) 람다식[Lamda Expression](4)
1제네릭, 람다식
클래스멤버사용 람다식에서 this는 람다식을 실행한 객체를 참조함.
로컬변수사용
람다식메소드 내부에서 작성되기에 익명구현객체
생성과 유사하다.
메소드의 매개변수와 로컬변수는 final특성을
갖게 되기 때문에 로컬변수를 람다식에서 읽기만 되고, 람다식 내/외부에서 변경할 수 없다.
표준API의
함수적인터페이스
표준API에서 한 개의 추상메소드를 갖는 인터페이스는 람다식을 통해 익명구현 객체로 표현이
가능함.
스레드작업을 정의하는 Runnable 인터페이스는 매개변수와 리턴값이 없는 run()메소드만 존
재하기 때문에 Runnable인스턴스를 람다식을 통해 생성가능.
다음은 java.util.function패키지의 함수적 인터페이스이다.
9.
7) 람다식[Lamda Expression](5)
1제네릭, 람다식
종류 추상메소드 특징
Consumer 매개값O 리턴값X
Supplier 매개값X 리턴값O
Function
매개값O 리턴값O
주로 매개값을 리턴값으로 매핑(타입변환)
Operator
매개값O 리턴값O
주로 매개값 연산결과를 리턴
Predicate
매개값O 리턴값O
매개값을 조사해서 참/거짓반환
10.
8) 람다식[Lamda Expression](6)
1제네릭, 람다식
메소드 참조
메소드 참조는 메소드를 참조해서 매개변수의 정보 및 리턴타입을 알아내서 람다식에서 불필요
한 매개변수를 제거하는 목적.
(x,y)->Math.max(x,y);//를 메소드참조로
Math::max;//이와 같이 변환
정적 메소드참조
static메소드는 클래스::메소드 로 기술
operator=Calc::staticMethod;
인스턴스
메소드참조
인스턴스메소드는 참조변수::메소드 로 기술
operator=(x,y)obj.instanceMethod(x,y);
매개변수의
메소드참조
매개변수a의메소드를호출해서 매개변수b를 매개값으로 사용할 수있음.
(a,b)->{a.instanceMethod(b);}
생성자참조 (a,b)->{return new 클래스(a,b);}
2 Multi-Thread
1) 멀티쓰레드의 개념
프로세스와 스레드
실행중인 애플리케이션을 Process라 부르고, 같은 애플리케이션을 여러 개 실행중일때 다중 프로세스라
한다.
멀티태스킹은 두가지 작업을 동시 처리함을 말하며, OS가 프로세스에 자원을 분할하면, 병렬실행한다.
스레드는 프로세스 내 멀티 태스킹으로 볼 수 있다.
메인스레드
자바프로그램은 메인스레드가 main()메소드를 실행하며 시작된다.메인스레드는 작업스레드를 만들어
병렬로 코드를 실행할 수 있도록 멀티쓰레드를 생성해 멀티태스킹을 수행한다.
작업스레드 생성
(직접생성
vs 하위클래스생성)
java.lang.thread클래스를 객체화 해서 생성해도 되지만 Thread를 상속해서 하위 클래스를 만들어 생성할
수 있다.
Thread클래스로 부터 직접 생성
Thread thread = new Thread(Runnable target);
Runnable은 작업스레드가 실행할 수 있는 코드를 가지고 있는 객체이며, 인터페이스 타입이다.
그래서 구현 객체를 만들어 대입해야하고, run()메소드를 구현 클래스에서 재정의해서 작업스레드가 실행
할 코드를 작성해야 한다.
class Task implements Runnable{public void run(){ ; } } } //재정의
Thread thread =new Thread( new Runable() { public void run() { ; } } );//익명구현객체로 재정의
thread.start();//스레드 구동
Thread 하위 클래스로부터 생성
thread의 하위 클래스로 작업 스레드를 정의하는 동시에 작업내용을 포함시킴.
public class WorkerThread extends thread{ @Override
public void run(){ ; } //run()메소드 재정의
Thread thread = new WorkerThread();
thread.start();
스레드 이름 Thread thread = Thread.currentThread(); thread.setName("쓰레드이름"); thread.getName();
13.
2 Multi-Thread
2) 쓰레드의우선순위
동시성(Concurrency)과
병럴성(Parallelism)
동시성 : 멀티 작업을 위해 하나의 코어에서 멀티스레드가 번갈아 가며 실행.
병렬성 : 멀티 코어에서 코어별 스레드를 동시에 실행.
싱글코어CPU의 멀티스레드 작업은 병렬적 실행으로 보이나, 동시성 작업이다.
스레드개수가 코어수보다 많으면, 어떤 순서에 의해 동시성으로 실행할 것인지 스레드 스케쥴링을
통해 정한다.
스레드 스케쥴링
스레드 스케쥴링은 우선순위(priority)방식과 순환할당(Round-Robin)방식을 사용.
우선순위 방식은 우선순위가 높은 스레드가 실행상태를 더 많이 갖음.
순환할당 방식은 시간 할당량 방식(Time Slice)를 정해서 돌아가며 실행하는방식.
우선순위 방식은 스레드 객체에 우선순위를 개발자가 부여하여 조작.
순환할당 방식은 JVM에 의해 제어됨.
우선순위는 1이 높고 10이 낮음. 기본값은 5. 우선순위 부여는 thread.setPriority(우선순위 값)
으로 제어.
thread.setPriority(Thread.MAX_PRIORITY);
thread.setPriority(Thread.NORM_PRIORITY);
thread.setPriority(Thread.MIN_PRIORITY);
14.
2 Multi-Thread
3) 동기화메소드와 동기화 블록(1)
공유 객체 사용시 주의점
멀티스레드 프로그램에서는 스레드간 객체 공유를 하게 되므로, 사용 중 객체에는 락을 걸어서 사용할 수 없도록 해야함.
멀티스레드프로그램에서 단하나의 스레드만 실행할 수 있는 영역을 임계영역(크리티컬 섹션)이라한다.
자바는 임계영역을 지정하기 위해 동기화(synchronized) 메소드와 동기화 블록을 사용.
public synchronized void setMemory(int m){this.memory=m;}
//동기화 메소드. 스레드가 이 메소드를 실행하는 동안 잠김
public void setMemory(int m){synchronized(this)//this는 잠금대상
this.memory=m;}//동기화 블럭으로 동기화 메소드 구현
스레드 상태
스레드는 new에 의해 스레드 객체가 생성되고 run()에 의해 Running(실행)상태를 갖고, 스케쥴링에 의해 대기상태(R
unnable)로 들어갔다가 실행을 반복하고, 종료(Terminated)된다.
일시정지상태는 WAITING, TIMED_WAITING, BLOCKED으로 구분되며, 이는 스레드를 실행할 수 없는 상태라서 실
행상태에서 실행대기 상태로 가지 않는다.
public StatePrintthread(Thread targetThread){//targetThread는 상태를 조사할 쓰레드)
this.targetthread=targetthread;}
public void run(){while(true){Thread.State stare=targetthread.getState();//스레드 상태 획득
System.out.println("타겟 스레드 상태 : "+state);
if(state==Thread.State.NEW){//객체생성상태인경우 실행대기상태로 만듬.
targetthread.start();}
if(state==thread.State.TERMINATED){break;}//종료상태인경우 반복문종료
스레드 상태 제어 실행중 스레드의 상태를 변경하는 것을 말함.
15.
2 Multi-Thread
4) 동기화메소드와 동기화 블록(2)
메소드 설명(Deprecate는 사용하지 않는 것이 권장되는 메소드)
interrupt()
일시정지 상태 스레드에서 interruptedException예외를 발생시켜
예외처리코드(catch)에서 실행대기 상태로 가거나 종료상태로 갈 수 있도록 한다.
notify()
notifyAll()
동기화블록 내에서 wait()메소드에 의해 일시정지 상태인 스레드를 실행대기 상태로 만든다.
resume()
suspend()메소드에 의해 일시정지 되어있는 스레드를 실행대기 상태로 만든다.
-Deprecate(대신 notify, notifyAll()사용)
sleep(long millis)
sleep(long millis,
int nanos)
주어진 시간동안 스레드를 일시정지 상태를 유지하고, 이후 실행대기 상태가 된다.
join()
join(long millis)
join(long millis, int nan
os)
join()을 호출한 스레드는 일시정지가 되고, 실행대기 상태가 되려면 join()메소드를 멤버로 가지는 스
레드가 종료되거나, 주어진 매개값 시간이 지나야한다.
wait()
wait(long millis)
wait(long millis,
int nanos)
동기화 블록 내에 스레들르 일시정지 상태로 만들고, 매개변수를 주면 주어진 시간 이후 실행대기로 변
경된다.
시간이 미설정이면 notify(), notifyAll()에 의해 실행대기 상태로 돌아갈 수 있다.
suspend()
스레드드를 일시정지 상태로 만든다. resume()이 호출되면 실행대기상태가 된다. - Deprecated(대
신 wait() 사용)
yield() 실행중 우선순위가 동일한 다른 스레드에게 실행을 양보하고 실행대기 상태로 변경
stop() 스레드 즉시 종료 - Deprecated
비고 wait, notify, notifyall은 Object클래스의 메소드이고, 그외는 Thread클래스의 메소드
16.
2 Multi-Thread
5) 동기화메소드와 동기화 블록(3)
스레드의 안전한
종료stop플래그,
interrupt()
stop플래스를 이용한 안전 종료
public class TheThread extends Thread{
private boolean stop;//stop플래스 필드
public void run(){
while(!stop){;}//stop이 true가 되면 run이 종료됨.
}}
interrupt()메소드를 이용하는 방법
try{Thread.sleep(1000);catch(InterruptedException e){}
thread.interrupt();
//스레드를 종료시키기위해 InterruptedException발생시킴.
데몬(daemon)
스레드
데몬스레드는 주스레드의 작업을 돕는 보조적 역할을 수행.
주 스레드가 종료되면 데몬스레드는 자동 종료됨
스레드 그룹
스레드 그룹은 스레드를 묶어서 관리할 목적으로 사용됨.
JVM이 실행되면 system스레드 그룹을 만들고, JVM운영에 필요한 스레드들을
생성해서 여기에 포함시킨다.
system의 하위 스레드 그룹으로 main을 만들고 메인스레드그룹에 포함시킨다.
17.
2 Multi-Thread
6) 동기화메소드와 동기화 블록(4)
스레드 이름 얻기
ThreadGroup group = Thread.currentThread.getThreadGroup();
String name=group.getName();
스레드 그룹 정보 얻기
Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();//Map타입의 객체
를 리턴하는 getAllStackTraces();
스레드 그룹 생성
ThreadGroup gtg=new ThreadGroup(String name);//또는 (ThreadGroup parent, String n
ame);
스레드를 스레드그룹에
배정
Thread t = new thread(ThreadGroup group, Runnable target);
Thread t = new thread(ThreadGroup group, Runnable target, String name);
Thread t = new thread(ThreadGroup group, Runnable target, String name, long stackSize
);
Thread t = new thread(ThreadGroup group, String name);
스레드그룹 일괄
interrupt()
그룹의 interrupt() 메소드를 한번만 호출함. 다만, 개별 스레드 예외처리는 하지 않아서 안전한 종료를
위해서는
개별 스레드마다 예외처리 해야한다.
18.
2 Multi-Thread
7) 동기화메소드와 동기화 블록(5)
메소드 설명[Deprecate된 메소드 : suspend(), resume(), interrupt(), stop()]
int activeCount() 현재 그룹 및 하위그룹에 활동중인 스레드 수를 리턴
int activeGroupCount() 현재 그룹에서 활동중인 모든 하위 그룹 수를 리턴
void checkAccess()
현재 스레드가 스레드 그룹을 변경할 권한이 있는지 확인한다. 만약 권한이 없으면 Security예외를 발
생 시킨다.
void destory() 현재 그룹 및 하위그룹을 모두 삭제한다. 단, 그룹내 포함된 모든 스레드들이 종료상태가 되어야 한다.
boolean isDestoryed() 현재 그룹이 삭제 되었는지 여부를 반환한다.
int getMaxPriority() 현재 그룹에 포함된 스레드가 가질 수 있는 최대 우선 순위를 반환한다.
void setMaxPriority(int
pri)
현재 그룹에 포함된 스레드가 가질 수 있는 최대 우선순위를 설정한다.
String getName() 현재 그룹의 이름을 리턴한다.
ThreadGroup getParent
()
현재 그룹의 부모 그룹을 반환한다.
boolean parentOf
(ThreadGroup g)
현재 그룹이 매개값으로 지정한 스레드 그룹의 부모인지 여부를 반환한다.
boolean isDaemon() 현재 그룹을 데몬 그룹으로 설정한다.
void setDaemon(boole
an dmn)
현재 그룹을 데몬 그룹으로 설정한다.
void list() 현재 그룹에 포함된 스레드와 하위 그룹에 대한 정보를 출력한다.
void interrupt() 현재 그룹에 포함된 모든 스레드들을 interrupt한다.
19.
2 Multi-Thread
8) 쓰레드풀(1)
개요
병렬 처리 작업이 증가하면 스레드 수도 증가하고 CPU가 바빠져서 메모리 사용량이 늘어나고 애플리케
이션 성능이 저하된다. 스레드 폭증을 막으려면 스레드 풀을 사용해야 한다.
스레드를 제한한 수만큼 정해놓고 작업큐에 들어오는 작업들을 하나씩 처리한다. 최대 스레드 개수를 정
해 놓아서 애플리케이션 성능이 급격히 저하되지 않는다.
생성
newCachedThreadPool() 메소드 : 초기 스레드 수=0, 코어 스레드 수=0,
최대 스레드 수=Integet MAX_VALUE
스레드 수보다 작업개수가 많으면 새 스레드를 생성시켜 작업 처리. 1개이상 스레드가 추가되면 60초동
안 추가된 스레드가 아무 작업을 하지 않을때 추가된 스레드를 종료하고 풀에서 제거한다. 이론적으로는
int값이 가질 수 있는 최대값만큼 스레드를 추가 할 수있으나, 운영체제 성능과 상황에 따라 달라진다.
ExecytorService executorService = Executors.newCachedThreadPool();
newFixedthreadPool(Int n)메소드 : 초기 스레드 수=0, 코어스레드수=n,최대 스레드수=n
최대 스레드 개수는 n이며, 스레드가 작업을 처리하지 않고 놀고 있더라도 스레드 개수를 줄이지 않는다.
ExecutorService executeorService = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
종료
void shutdown() - 현재 처리중인 작업뿐만 아니라 작업큐에 대기하고 있는 모든 작업을 처리한 후
스레드풀 종료
List<Runnable> shutdownNow() - 현재 작업 처리 중인 스레드를 interrupt해서 작업 중지를 시도
하고 스레드 풀을 종료, 작업큐에 있는 미처리된 작업(Runnable)목록을 반환.
boolean awaitTermination(long timeout, TimeUnit unit) - shutdown() 메소드 호출 이후 모
든 작업 처리를 timeout시간 내에 완료하면 true반환, 그렇지 못하면 처리중인 스레드를 interrupt
하고 false 를 반환한다.
20.
2 Multi-Thread
9) 쓰레드풀(2)
작업 생성
작업은 Runnable 또는 Callable 구현 클래스로 표현된다.
Runnable task = new Runnable(){// 작업 처리 완료후 반환값이 없음.
@Override
public void run(){;}}
Callable<T> task = new Callable<T> {// 작업 처리 완료후 반환값이 있음.
@Override
public T call() throws Exception{;return T;}}
작업 처리 요청
ExecutorService의 작업큐에 Runnable 또는 Callable 객체를 넣는 행위를 말함.ExecutorService
는 작업 처리 요청을 위해
다음 메소드를 제공한다.
void execute(Runnable cmd) - Runnable을 작업 큐에 저장 / 작업 처리 결과를 받지 못함.
Future<?> submit(Runnable task) - Runnable 또는 Callable을 작업 큐에 저장 / 반환된 Future
를 통해 작업처리 결과획득
Future<V> submit(Runnable task, V result)
Future<V> submit(Callable<V> task)
submit은 작업처리 결과를 받을 수 있도록 Future를 제공하고,
execute는 작업처리 결과를 받지 못한다.
21.
2 Multi-Thread
10) 쓰레드풀(3)
블로킹 방식의
작업 완료 통보
Future객체는 작업 결과가 아니라 작업이 완료될때까지 기다렸다가(지연했다가=블로킹되었다가)최
종 결과를 얻는데
사용된다. 그래서 Future를 지연완료(pending completion)객체라 한다.
V get() - 작업이 완료될때까지 블로킹 되었다가 처리결과 V를 반환
V get(long timeout, TimeUnit unit) - timeout 시간 전에 작업이 완료되지 않으면 Timeout예외
발생
반환타입 V는 submit(Runnable task, V result)의 두번째 타입인 V타입이거나,
submit(Callable<V> task)의 Ballable타입 파라미터 V타입이다.
submit은 작업도중 예외발생시 예외발생시킴.
submit(Runnable task) future.get() -> 작업 완료후 null반환
submit(Runnable task, Integer result) future.get() -> 작업 완료후 int값 반환
submit(Callable<String> task) future.get() -> 작업 완료후 String 값반환
boolean cancel(boolean mayInterruptIfRunning) - 작업 처리가 진행중일 경우 취소 시킴
boolean isCancelled() - 작업이 취소되었는지 여부 반환
boolean isDone() - 작업이 완료되었는지 여부 반환
22.
2 Multi-Thread
11) 쓰레드풀(4)
반환값이 있는 작업 통보
Callable<T> task = new Callable<T>{
@Override
public T call() throws Exception{; return T;}}};
Future<T> future = executorService.submit(task);
작업 처리 결과
외부객체에 저장
Result result= …;
Runnable task = new Task(result);
Future<Result> future = executorService.submit(task, result);
result = future.get();
23.
2 Multi-Thread
12) 쓰레드풀(5)
작업 완료 순으로 통보
Future<V> poll() - 완료된 작업의Future를 반환. 완료된 작업이 없다면 즉시 null을 반환
Future<V> poll(long timeout, TimeUnit unit) - 완료된 작업의Future를 반환. 완료된 작업이 없
다면 timeout까지 블로킹됨
Future<V> task() - 완료된 작업의Future를 반환. 완료된 작업이 없다면 있을때 까지 블로킹됨
Future<V> submit(Callable<V> task) - 스레드풀에 Callable 작업 처리 요청
Future<V> submit(Runnable task, V result) - 스레드 풀에 Runnable 작업 처리 요청
콜백방식의 작업 완료 통보
Runnable task = new Runnable(){
@Override
public void run(){
try{
//작업처리
V result=..;
callback.complited(result, null);//작업을 정상 처리한 경우 호출
}catch(Exception e){callback.failed(e, null);}}};//예외가 발생하면 호출