Thread & Network

JooH·2024년 1월 3일
0

NHN_BackendAcademy

목록 보기
2/23

syncronized

자바는 virtual machine에서 동작하니 sync를 언어수준에서 처리할 수 있다.
앞서 설명하였듯 mutex는 lock/unlock을 사용하여 deadlock을 막는것에 목적이 있고,
semaphore는 자원 할당에 목적을 가지고 있다. (관점은 다른데 기능은 같다)

sync를 구현하는 방법은 다음과 같다. (기본적으로 sync는 static으로 구성한다)

instance method
class method
code block

Wait & Notify :
wait() : sync 영역에서 lock을 소유한 thread가 자신의 제어권을 양보하고 waiting, timed-waiting에서 대기.
notify() : sync 영역에서 Waiting 상태인 다른 thread를 Runnable state로 변경
notify-> 아무 쓰레드나 1개, notifyAll : 모든 waiting 쓰레드 기상

wait() 의 장점 : 버퍼가 비었을 때, cpu가 계속 checking 하는게 아니라 notify()가 올때까지 sleep 상태로 대기한다.

생명주기

Thread의 생명주기는 Process의 생명주기와 유사하게
new, runnable, running, waiting, timed-waiting, terminated로 구성되어있다.

Thread 상태제어 함수

interrupt :
waiting 대상에 interrupt를 발생시켜 runnable 상태로 변경.

wait vs sleep:
wait -> 가지고 있는 lock()을 해제 후 waiting
sleep -> 호출시 가지고 있는 lock과 상관없이 timed_waiting
waiting 상태에 있는 thread는 동일한 잠금에서 notify 해 깨울 수 있음.
sleeping 상태에 있는 thread는 notify 해도 못깨움. interrupt시 InterruptedException 에러

Join : join 선언한 쓰레드가 끝날때 까지 대기. 내부에 milisec 넣었을 경우, 지정된 시간까지만 기다림.

Thread Pool

여러 Thread를 여러번 사용하며, pool 자체는 여러번 재사용 되는 thread 그룹.
고정크기로 생성되기 때문에, pool이 너무 크면 메모리 낭비가 생기고 너무 작으면 안쓰는거랑 차이가 없다.

장점 : Thread 생성과 삭제에 따른 시간과 resource 절약
단점 : DeadLock, Thread Leakage - 비정상 종료에 의한 실행종료, Resource Trashing - 지나치게 pool이 크면 context switing시 느려짐

Daemon Thread

데몬 쓰레드 : 백그라운드에서 작동하는 쓰레드로, 마지막 남은 유저 쓰레드가 사라질때까지 대기하다가, 유저쓰레드가 사라지면 같이 사라짐. 주로 main thread나 다른 user thread의 보조역할 혹은 특정작업을 주기적으로 처리하는 thread 등에 주로 사용됨.

Network

Socket

네트워크에서 정보가 전송되는 고유 식별자
http <-> https (보안차이, 443번 사용)
https://www.~~~.:1880/ (port 1880번 쓰겠다)

OSI 7단계, TCPIP 4 layer protocol

소켓의 종류 -

데이터 그램 소켓 :

보내고 끝! 받는건 관심없다.
udp : user datagram protocol. 무연결 소켓(뭔가 연결할때 established를 안함)
둘간의 상관관계가 없음, 기본적으로 포트는 열려있고 주는건 다 받음.(열리면받고 아니면 말고, 관심없음) 따라서 신뢰성이 전혀 보장 되지 않는다. 따라서 최상위 어플리케이션에서 통신이 되는지 확인을 해야한다.
장점 ) 확인이 필요없는 상황에는 udp가 좋다. 가끔 데이터가 손상되도 상관없는것들이 있음.

스트림 소켓 : 연결 기반 소켓

TCP transmission control protocol,
SCTP - 동영상 볼때 사용. 시간제어 등...사용시사용
DCCP -
상대쪽에서 받았는지 tcp가 확인하기 때문에 당연히 안정성이 좋다. 하지만 반대로 속도는 udp보다 느리다. (ack)를 사용해서 확인.

raw socket -- 쓸일이 거의 없음..

소켓 통신

간단하게 client - server 구분하는 방법
서버 - 포트를열고 기다리는 쪽
클라이언트 - 접속을 시도하는 쪽

서버 소켓
bind() : 소켓을 포트에 binding 해줌. 소켓과 포트를 묶어서 바인딩
listen() : 바인딩한것으로 listen. 아무도 안쓰는 포트로 binding 한다. 대기모드
accept() : 대기모드에서 connect 시도 -> 해당 포트가 있으면accecpt // 없으면 error
accept시 연결된 쪽은 떨쳐주고 하나는 listen 상태로 간다.(thread 사용) - 연결요청이 오면 accpet 이용해 연결 승인한다.
요청은 client socket과 통신을 위한 소켓 생성
이상적인 것은 connect() 요청 하는 한명당 1개의 쓰레드 생성하는 것.(?)

서버는 다중접속을 허용 할수도 안할수도 있다.
쓰레드로 connect를 따로 뗀다 -> 다중접속 허용
안한다 -> 불허

클라이언트 소켓
소켓생성
connect 써서 연결요청 전송
요청 허용하면 전송 시작 ( 같은 level async 통신 )

자바의 소켓통신

자바는 socket class, server socket class 둘다 지원한다.
서버 소켓을 생성 하면서 bind, listening등 의 과정을 한번에 처리(단순화해준다)
또한 이 과정에서 에러가 발생하면 Exception을 알린다

Accept() 가 서버 클라이언트에서 통과되면 서로 같은 소켓이 된다(서로 통신하니까).

서버와 연결됬다고 해도 바로 메시지를 보낼수 있는게 아니라 java는 iostream을 통해 전송해야 한다.
--> 매체가 바뀌더라도 내 코드는 바뀔 필요가 없다. stream으로 보낸다/받는다.(abstraction 사용)

0개의 댓글