728x90
반응형
01.쓰레드 그리고 동기화
- 시간이 지나가면서 program 만드는 속도가 많이 줄어듦
- 이전에 비해 많이 줄어듦
- 이전에 1 ~ 10가지 기술로 개발을 해야했다면 전체를 다 알고 개발을 했음
- 예를 들어 쓰레드라는 기술이 필요하다면 전부를 알아야했다 물론 전부를 알고 있으면 좋긴함
- 요새는 위의 10가지 기술을 기반 기술이라고 한다면 이것을 비슷한 여러개를 하나로 묶음
- 이를 프레임워크라는 용어로 쓰인다고 함, 요즘은 이런 프레임 워크가 많아져서 하나하나 구현할 필요가 없어지는 것
- 요즘은 속도를 더 중요시하지는 않는다 얼마나 원하는 것을 구현하는가를 중요시 함
02.쓰레드 이해와 생성
- 실행중인 프로그램을 프로세스라고 함
- 그 프로세스에서 일이나 작업
- java에서 main()역시 쓰레드이다.
- 흐름을 만드는 주체, 최소단위를 말함
- 멀티 쓰레드는?
- 하나의 프로세스 안에 2개이상의 쓰레드가 있는 것
Thread ct = Thread.currentThread(); String name = ct.getName();//쓰레드의 이름을 받아옴
- 쓰레드 과정
- Runnable을 구현한 인스턴스 생성
- Thread 인스턴스 생성
- Start 메소드 호출
Runnable task = () -> { int n1 = 10; int n2 = 20; String name = Thread.currentThread().getName(); System.out.println(name + " : " + (n1 + n2)); } Thread t = new Thread(task); t.start();//쓰레드 생성 및 실행
03.둘 이상 쓰레드 생성
Runnable task1 = () -> {
//로직1
}
Runnable task2 = () -> {
//로직2
}
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task2);
class Task extends Thread{
public void run(){
}
}// 이것과 같이 클래스로도 가능하다 하지만 요새는 람다식이 잘되어 있어 람다식으로 한다.
03.1 Join()
- 쓰레드의 종료를 기다린다.
- 쓰는 것은 쓰레드가 완료된 후 결과를 출력하고 싶은 경우 쓰레드가 종료하기를 기다리기 위해 사용하는 것
04.쓰레드의 동기화
- 싱글 쓰레드에서는 문제가 없음
- 멀티쓰레드를 사용했을 경우 문제가 발생
- 공유자원에 대한 문제가 발생
- 쓰레드로 count++ 하는 로직 하나와 count--하는 로직을 만들었을때
- 이상적으로 우리는 100번 씩 했다하면 0이 나와야한다고 생각한다.
- 하지만 우리가 생각한것처럼 0이 나오지 않는다
- 이것의 문제가 공유자원을 접근했을때 다른 쓰레드의 동작이 끝나지 않은상태에서 또다른 쓰레드가 공유자원을 가져와서 쓰기 때문에 문제가 발생하는것
- 위의 문제를 방지하기위해서 공유자원을 다른 쓰레드가 쓰고 있을 때 쓰지 못하게 하는 것 이를 쓰레드의 동기화라고 한다.
- 상호배제를 하는것이라고 생각하면 쉽다.
04.1 동기화는 어떻게 하나요?
- synchronized를 선언해주면 됨
-
synchronized public void increment(){};
- 동기화 블럭
-
synchronized (this){ count++; }
05.쓰레드를 생성하는 더 좋은 방법
- 쓰레드 풀 모델
- 쓰레드 생성과 소멸은 리소스 소모가 많음
- 쓰레드 풀은 쓰레드를 재활용하기 위한 모델
- 여러개 작업이 있는 경우 몇개의 쓰레드가 필요하는지? 이것을 선택하는것이 어려운 문제이다
- 어떤 프로그램은 싱글쓰레드로 쓰는것이 오히려 성능면에서도 좋기에 적절히 써야한다.
ExecutorService exr = Executors.newSingleThreadExecutor();
exr.submit(task);// 여기서 task는 우리가 만드는 로직이고 쓰레드 풀에 작업 전달
exr.shudown();// 쓰레드 풀과 그 안에 있는 쓰레드 소멸
05.1쓰레드 풀의 유형
new SingleThreadExecutor;
new FixedThreadPool(3);//숫자만큼 쓰레드 생성유지
new CacheThreadPool; //작업의 수에 맞게 유동적으로 관리
06.Callable & Future
- main() 쓰레드에 t1, t2가 있을때 각각의 쓰레드한테 t1은 1 ~ 50 , t2는 51 ~ 100 하라고 하는것
- 이런것을 가르켜 워크 쓰레드라고 함
- 단, 이렇게 하면 main()쓰레드가 취합해야한다 그렇기 때문에 때에 따라서 쓰레드가 연산 결과를 반환해야함
- 이전의 쓰레드는 반환 값이 void라서 그렇게 안됨
- before
-
public interface Runnable{ void run(); }
- after
-
Functional Interface public interface Callable<V>{ V call() throws Exception; }
- 실제 사용법
-
public static void main(String[] args) throws InterruptedException, ExecutionException{ Callable<Integer> task = () -> { int sum=0; for(int i=0; i<10; i++){ sum+=i; } return sum; }; ExecutorService exr = Executors.newSingleThreadExecutor(); Future<Integer> fur = exr.submin(task); Integer r = fur.get();//스레드의 반환 값 획득 System.out.print }
07.syncronized 대신하는 ReentrantLock
class MyClass{
ReentrantLock criticObj = new ReetrantLock();
void myMethod(int arg){
criticObj.lock();
//...
criticObj.unlock();
}
}
- 권고
-
class MyClass{ ReentrantLock criticObj = new ReetrantLock(); void myMethod(int arg){ criticObj.lock(); try{ //... }finally{ criticObj.unlock(); } } }
08.컬렉션 인스턴스 동기화
public static <T> Set<T> syncronizedSet (Set<T>s)
public static <T> List<T> syncronizedSet (List<T>list)
public static <K,V> Map<K,V> syncronizedSet (Map<K,V>m)
public static <T> Collection<T> syncronizedSet (Collection<T>c)
- 사용
- 중요한점 이렇게 하더라도 반복자를 써서 저장을 하면 그 반복자 자체를 동기화 해주는것이 아님
- 그렇기 때문에 반복자 역시 동기화를 해줘야함
- 중요한점 이렇게 하더라도 반복자를 써서 저장을 하면 그 반복자 자체를 동기화 해주는것이 아님
-
List<String> lst = Collections.syncronizedList(new ArrayList<String>());
- before | 제대로 동기화 안됨
-
Runnable task = () -> { ListIterator<Integer> itr = lst.listIterator(); while(itr.hasNext()) itr.set(itr.next()+1); }
- after | 제대로 동기화됨
-
Runnable task = () -> { syncronized(lst){ ListIterator<Integer> itr = lst.listIterator(); while(itr.hasNext()) itr.set(itr.next()+1); } }
728x90
반응형
'CS Study > JAVA' 카테고리의 다른 글
2022-05-24-자바-상속이란 (0) | 2022.05.24 |
---|---|
2022-05-21-자바와-코틀린의차이 (0) | 2022.05.24 |
2022-04-23-자바-기초정리1 (0) | 2022.04.24 |
2022-04-23-자바의-메모리-모델과-Object-클래스 (0) | 2022.04.24 |
2021.10.05_java-static (0) | 2021.10.05 |
댓글