JAVA/Basic

[스터디할래? Java 10]멀티쓰레드 프로그래밍

[스터디할래? Java] 목차

이글은 백기선님 스터디 할래? 스터디를 뒤늦게 따라간 기록입니다.

스터디할래 링크 >> https://github.com/whiteship/live-study

이필기를 시작으로 공부했습니다 >> https://sujl95.tistory.com/63 

                                               , https://wisdom-and-record.tistory.com/48

여기 없는내용은 스터디 할래 강의 내용 혹은 제가 java Doc보고작성하거나 예제를 만들어 추가했습니다.

그외는 같이 출처가 써있습니다. 

 

프로세스 와 쓰레드 프로세스 : 자원(resources, 데이터+메모리) + 쓰레드 
쓰레드 : 프로세스의 자원을 이용해 셀제 작업을 수행하는것. 
 Runnable vs Thread Runnable : 함수형인터페이스
package java.lang;
public interface Runnable {       
    public abstract void run();
}
---------------
Thread : 클래스, 쓰레드 그룹등 사용가능 
package java.lang;
public class Thread implements Runnable {

--------------
run() 말고 다른것도 재정의가 필요하면 thread상속, run()만 수정하면 Runnble 사용. 
thread는 순서대로 실행되지 않는다. 
suspend(), resume(), stop()//쓰레드종료 안전성때문에 Deprecated
쓰레드는 코어수와 비례
Thread 종류 - 일반쓰레드 : 
- 데몬쓰레드 : 일반쓰레드 보조역할, GC.자동저장, 갱신등 사용. 
                   일반쓰레드 종료시 같이 종료. 보통무한루프로 구현.
                   쓰레드.setDaemon(True) 하면 데몬쓰레드 지정

- 메인쓰레드 : 프로그램 시작시 가장 먼저 실행 쓰레드, 
public static void main(Stringp[] args){}  메인 쓰레드의 시작점 선언
따로 쓰레드 실행하지 않고 main() 메소드만 실행하면 싱글 쓰레드 애플리케이션

JVM -> Other Daemon Threads(ex_ Gc)
       -> MainThread -> Child ThreadA
                            -> Child ThreadB -> child ThreadC
                            ->         ...
Thread 메서드 static void sleep(long millis) : 지정시간 쓰레드 일시정지 -> TIMED_WAITING
void join()   : (지정시간)실행, 호출한 쓰레드 일시정지 호출 실행 완료 후에 재개
void join(long millis)
void interrupt() : sleep(), join() 일시정지 -InterruptedException->  실행대기로 만듬
static void yield() : 실행중에 자신에게 주어진 실행시간 다른쓰레드 양보, 자신은실행대기
public synchronized void start() 호출
쓰레드의 상태     public enum State {
        NEW,                  //객체만 생성 start() 미호출
        RUNNABLE,          // start() 쓰래드 실행
        BLOCKED,            //쓰레드 실행중지, 락이 풀리는것 대기
        WAITING,            //쓰레드 대기중
        TIMED_WAITING,  //특정 시간만큼  대기중 
        TERMINATED;      //쓰레드가 종료
    }

New  -(start())----> Runnable              -> Terminated
                           --------------------
                          -> Blocked
                          -> Waiting           
                          -> Timed Wating 
쓰레드의 우선순위 쓰레드.setPriority(int newPriority)
    public final static int MIN_PRIORITY = 1;       //최소
    public final static int NORM_PRIORITY = 5;   //기본값
    public final static int MAX_PRIORITY = 10;    //최대
runnable vs callable  Runnable :어떤 객체도 리턴하지 않음 , Exception발생시키지 않음
Callable: 특정타입 객체 리턴 Exception 발생가능
public interface Callable<V> {
    V call() throws Exception;
}
https://codechacha.com/ko/java-callable-vs-runnable/
Object의
thread관련 메소드
wait() , wait(long timeout), wait(long timeout, int nanos)
: 동기화블록내  쓰레드를 해당객체 waiting pool에 넣는다. 
notify(), notifyAll()
: 동기화블록내 waitng pool 대기중인 쓰래드를 깨운다. 
synchronized 동기화 
: 여러개의 쓰레드가 한 개의 리소스를 사용하려고 할 때 사용 하려는 쓰레드를 제외한 나머지 접근못하게 함. (Thread-safe)

구현
- Synchronized 키워드 : 동기화블록, 메소드 선언시, 메소드내 특정 문장 감싸기
                                범위가 좁게 사용하는것을 추천. 그래서 동기화블록사용이 적합..
- Atomic 클래스: java.util.concurrent
: 여러쓰레드 접근해도 원자적 접근 데이터 구조 ,한쓰레드씩 접근사용.
- Volatile 키워드 : java 변수를 메인메모리 저장 명시, multi thread 환경 cpu cache값 불일치 문제 때문에 사용. ,한쓰레드씩 접근사용.

Lock  jdk1.5 락. : 상호 배재를 사용할수 있는 클래스 제공
package java.util.concurrent.locks;
public interface Lock {
    void lock();                  // 잠근다.
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();               //해지한다.
    Condition newCondition();
}
lock구현체
- ReentrantLock              : 재진입가능, 가장일반적임
- ReentrantReadWriteLock : 읽기공유가능 쓰기 lock
- StampedLock                 : ReentrantReadWriteLock 에 기능추가. 
DeadLock   교착상태 
둘 이상의 쓰레드가 lock 을 획득하기 위해 대기 하는데 
대기하는 쌍방이 우위를 가리수 없어 어느쪽도 진행되지 않는상태(block)

Thread 1 rocks A, waits for B
Thread 2 locks B, waits for A

동시성 vs 병렬성 concurrency programming model,
: 동시성 프로그래밍 모델 ex_자바쓰레드

Parallelism programing model
: 병렬성 프로그래밍 모델
- critical path : 동시 실행 하는것중 가장 긴거.. 이것을 줄여야 수행시간이 줄다.
----
-----------
---- 
              -----------------
              -----
              -------
                                  ---------
                                  -------------
                                  --------
race condition: 어떻게 접근하느냐에 따라 결과가 달라지는 경우. 

추천책 : 자바 병렬프로그래밍...이출판사 번역신경쓰니참고.

 

thread.. 서버 수준 구현 할때만 필요. ex) tomcat

톰캣 최종분석...톰캣을 만들어봄.... ㅋㅋㅋOTL

요즘 컨테이너는 NIO Connector 사용...

 

동시 프로그래밍 모델: concurrency programing model 

 - 예 자바 쓰레드, Actor Model -아카..., STM(Software Trancsaction memory)- closer

  당시 actor가 가장빠름. contention 이 없어서.. 자원충돌날것이 없음. 

동시성 vs 병렬성

free lunch is over 

: CPU 클럭속도 한계가 와서 더많은 코어를 잘쓸수있는 방향으로. >>멀티쓰레딩 패러다임이 바뀌고 있다. 

무어의 법칙이... 주춤해짐...년 혹은 18개월마다 반도체의 집적도는 2배가 된다

 

Volatile 볼레틸 휘발성 

 

Thread, runnable 구현

package study;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadExample  {
    public static void main(String[] args) {
        Thread byThread = new ThreadByThread();
        byThread.start();

        Runnable runnable  = new ThreadByRunnable();
        Thread byRunnable = new Thread(runnable);
        //byRunnable.run();

        byRunnable.start();
        Lock lock= new ReentrantLock();
    }

    public static void print(String threadInfo , int num){

        for (int i =0; i<100;i++)
            System.out.println(threadInfo + " | " + num);
    }
}

class ThreadByThread extends Thread{
    @Override
    public void run() {
        ThreadExample.print(Thread.currentThread().getName(), 1);
    }
}

class ThreadByRunnable implements Runnable{
    @Override
    public void run() {
        ThreadExample.print(Thread.currentThread().getName(),0);
    }
}

강사님 설명소스. 

package study;

public class ThreadExample  {
    public static void main(String[] args) {
        Thread byThread = new ThreadByThread();
        byThread.start();

        new Thread(()->ThreadExample.print(Thread.currentThread().getName(), 0)).start();
    }

    public static void print(String threadInfo , int num){

        for (int i =0; i<100;i++)
            System.out.println(threadInfo + " | " + num);
    }
}

class ThreadByThread extends Thread{
    @Override
    public void run() {
        ThreadExample.print(Thread.currentThread().getName(), 1);
    }
}

  • Thread 클래스와 Runnable 인터페이스
  • 쓰레드의 상태
  • 쓰레드의 우선순위
  • Main 쓰레드
  • 동기화
  • 데드락