Java Concurrency
Thread 생성- 자바에서 스레드를 생성하는 방법은 2가지 이다. java.lang.Thread와 java.lang.Runnable 2가지가 있다.
Thread를 상속받는 방법.
class Comet extends Thread {
public void run() {
System.out.println("Orbiting");
orbit();
}
}
Comet halley = new Comet();
hally.run();
Runnable를 구현하는 방법.
class Asteroid implements Runnable {Lambda 표현식을 이용하는 방법.
plublic void run() {
System.out.println("Orbiting");
orbit();
}
}
Asteroid majaAsteroid = new Asteroid();
Thread majaThread = new Thread(majaAsteroid);
majaThread.run();
Runnable asteroid = () -> {
System.out.println("Orbiting");
orbit();
}
Thread asteroidThread1 = new Thread(asteroid);
Thread asteroidThread2 = new Thread(asteroid);
asteroidThread1.run();
asteroidThread2.run();
Thread 상태
NEW : 스레드는 생성되었으나 시작되지 않은 상태.RUNNABLE : 스레드가 실행 가능한 상태가 되었다.
BLOCKED : "alive" 스레드로 모니터 락을 기다리는 블록된 상태.
WAITING : "alive" 스레드로 다른 스레드를 기다리는 동안 wait()혹은 join()을 호출한다.
TIMED_WAITING : "alive"스레드로 특정 시간동안 다른 스레드를 기다린다. sleeping
TERMINATED : 스레드가 완료된 경우
스레드 우선순위
스레드 우선순위는 1 ~ 10단계로 둘수 있다. 기본은 5이다.MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY 를 이용하여 우선순위를 탐색 할 수 있다.
System.out.println(Thread.MAX_PRIORITY);낮은 우선순위는 높은 우선순위의 스레드에 양보하게 된다.
공통 메소드
getPriority() : 스레드의 우선순위를 반환한다.getState() : 스레드의 상태를 반환한다.
interrupt() : 스레드에 인터럽트를 건다.
isAlive() : 스레드가 얼라이브 상태인지 검사한다.
isInterrupted() : 스레드가 인터럽트 되었는지 검사한다.
join() : 이 메소드를 호출하여 스레드를 기다린다. 이는 객체가 종료 되었음을 알려준다.
setPriority(int) : 스레드의 우선순위를 설정한다.
start() : 스레드를 실행 가능 상태의 위치로 옮긴다.
notify() : 스레드에게 깨어나고, 실행하라고 해준다.
notifyAll() : 모든 기다리는 스레드나 리소스에게 깨어나게 한다. 그리고 스레드 중의 하나를 선택해서 실행한다.
wait() : 다른 스레드가 notify를 호출하거나 notifyAll()을 호출하기 전까지 대기 하게 한다.
# 중요 :
만약 wait() 와 notify()를 호출할때 스레드의 상태가 interrupted flag가 true로 설정된 경우 InterruptedException이 발생된다.
정적 스레드 메소드 :
activeCount() : 현재 스레드 그룹에서 스레드의 수를 반환한다.currentThread() : 현재 실행중인 스레드의 레퍼런스를 반환한다.
interrupted() : 현재 실행중인 스레드의 인터럽트 여부를 체크한다.
sleep(long) : 지정된 밀리 세컨동안 실행되는 스레드를 블록한다.
yield() : 현재 스레에게 다른 스레드가 수행할 수 있도록 알려준다.
Synchronization
synchronized 키워드는 특정 블록이나 메소드에게 락을 수행하도록 해준다.Locks는 블록이나 메소드에 걸리며 이는 매우 중요하게 공유되어야할 리소스에 접근할때 이용하게 된다. 이 모니터 락은 브레이스를 열고 닫는 것으로 시작과 종료가 된다.
객체 인스턴스 t에 동기화 락을 걸어준다.
synchronized (t) {객체 인스턴스 this 에 동기화 락을 걸어준다.
// Block body
}
synchronized (this) {raise() 메소드에 동기화 락을 걸어준다.
// Block body
}
synchronized void raise() {
// Method body
}
void raise() {상기 두 처리는 동일하다.
synchronized (this) {
// Method body
}
}
다음은 정적 메소드에 동기화 락을 걸어 준 예이다.
class Telescope {
synchronized static void calivrate() {
// Method body
}
}
동시성 유틸리티
java에서는 java.util.concurrent 패키지를 제공하여 동시성을 지원하고 있다. 이는 executors와 concurrent collections, synchronizers, timing 유틸리티를 포함하고 있다.Executor
ThreadPoolExecutor과 같이 ScheduledThreadPoolExecutor 은 Executor을 구현한 인터페이스이다. 이는 설정 가능하고, 유동적인 스레드 풀을 제공한다.스레드 풀은 스레드의 재사용 가능하도록 해준다.
Executors는 팩토리를 제공한다. 다음은 스레드 풀을 생성하기 위한 내용을 보여준다.
newCachedThreadPool()
- unbounded 스레드 풀을 생성하며, 자동적으로 재 사용 가능한 스레드이다.
newFixedThreadPool(int nThreads)
- 고정 크기의 스레드 풀을 생성한다. 이것은 공유된 unbounded 큐를 끈 스레드를 재사용 하도록 한다.
newScheduledThreadPool(int corePoolSize)
- 스레드 풀을 생성하며, 스케줄 된 커맨드를 가진 주기적인 실행 혹은 지정된 딜레이를 가진 스레드 풀을 지원한다.
newSingleThreadExecutor()
- 단일 스레드 executor을 생성하고, unbounded 큐를 끈 처리를 수행한다.
newSingleThreadScheduledExecutor()
- 단일 스레드 executor을 생성하고 지정된 기간 혹은 특정 딜레이에 의한 스케줄된 커맨드를 가질 수 있다.
다음은 newFixedThreadPool 팩토리 메소드를 사용한 예제이다.
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class ThreadPoolExecutor {
public static void main() {
// 태스크를 생성한다.
RTask t1 = new RTask("thread1");
RTask t2 = new RTask("thread2");
// 스레드 매니저를 생성한다.
ExecutorService threadExecutor = Executors.newFixedThreadPool(2);
// 스레드를 실행 가능 상태로 만든다.
threadExecutor.execute(t1);
threadExecutor.execute(t2);
// 스레드를 셧다운 한다.
threadExecutor.shutdown();
}
}
Concurrent Collections
컬렉션 타입을 동기화된 방식으로 제공한다. 이는 thread-safe 한 처리를 지원한다.HashMap <--> ConcurrentHashMap
TreeMap <--> ConcurrentSkipListMap
TreeSet <--> ConcurrentSkipListSet
Map subtypes <--> ConcurrentMap
List subtypes <--> CopyOnWriteArrayList
Set subtypes <--> CopyOnWriteArraySet
PriorityQueue <--> PriorityBlockingQueue
Deque <--> BlockingDequeue
Queue <--> BlockingQueue
Synchronizers
Synchronizers는 특별한 목적을 위해 만들어진 동기화 툴이다.Semaphore : 허가들의 집합을 관리한다.
CountDownLatch : 막 수행된 오퍼레이션의 집합에 대한 waits를 구현한다.
CyclicBarrer : 공통 장벽 지점에 대한 waits를 구현한다.
Exchanger : 동기화 포인트를 구현하며, 스레드들이 변화시킬 수 있는 엘리먼트에 구현한다.
Timing Utility
TimeUnit은 enumeration으로 시간 기반의 메소드에 공통으로 사용된다. 이것은 시간 파라미터가 어떤 단위로 진행될지 지정하며, 다음과 같다.if (lock.tryLock(15L, TimeUnit.DAYS)) {...} // 15일 락을 시도한다.
NANOSECONDS : 1/1000us 나노초
MICROSECONDS : 1/1000ms 마이크로초
MILLISECONDS : 1/1000sec 밀리초
SECONDS : sec : 초
MINUTES : 60sec : 60초
HOURS : 60min : 3600초
DAYS : 24hr : 86400초
from : java 8 pocket book
EmoticonEmoticon