Notice
Recent Posts
Recent Comments
Link
passion and relax
[JAVA] 15. 연결하는 방법 (네트워크 소켓과 멀티스레딩) 본문
간단한 서버-클라이언트 소켓 통신 예
server
public class DailyAdviceServer {
String[] adviceList = {"aaa", "bbb", "ccc"};
public void go() {
try {
ServerSocket serverSock = new ServerSocket(4242);
while(true) {
Socket sock = serverSock.accept();
PrintWriter writer = new PrintWriter(sock.getOutputStream());
writer.println(adviceList[(int) (Math.random() * adviceList.length)]);
writer.close();
}
} catch (IOException ex) {
Logger.getLogger(DailyAdviceServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
DailyAdviceServer server = new DailyAdviceServer();
server.go();
}
}
client
public class DailyAdviceClient {
public void go() {
try {
Socket s = new Socket("localhost", 4242);
InputStreamReader sReader = new InputStreamReader(s.getInputStream());
BufferedReader r = new BufferedReader(sReader);
String advice = r.readLine();
System.out.println(advice);
r.close();
} catch (Exception ex) {
Logger.getLogger(DailyAdviceClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
DailyAdviceClient client = new DailyAdviceClient();
client.go();
}
}
간단한 스레드 예
public class MyRunnable implements Runnable {
@Override
public void run() { go(); }
public void go() { doMore(); }
public void doMore() { System.out.println("top o' the stack"); }
}
class ThreadTester {
public static void main(String[] args) {
Runnable threadJob = new MyRunnable();
Thread myThread = new Thread(threadJob);
myThread.setName("HaHa"); //스레드 기본 이름 무시하고, 새 이름 부여
myThread.start();
System.out.println("back in main");
}
}
스레드의 상태
새로운 스레드
Thread t = new Thread(r);
실행 가능한 상태 (실행 중은 아님)
t.start();
실행 중인 상태
스레드 스케줄러에 의해, 이 스레드가 선택되었을 때 실행된다.
다시 실행 가능한 상태
실행 중인 상태에서 다른 스레드에 기회를 주기 위해 실행 가능한 상태로 다시 빠짐
봉쇄 상태 (일시적인 실행 불가능 상태)
스트림으로 부터 들어오는 데이터를 기다리고 있을 때
대기 상태로 들어 갔을 대
객체에 대한 잠금이 해제되기를 기다리고 있을 때
Thread.sleep()
실행 중인 상태에서 실행 가능한 상태로 강제 전환
실행 가능한 상태로 갔다가 다시 스레드 스케줄러에 의해 선택되어질 때까지 실행되지 않는다.
즉, 설정한 sleep() 시간 보다 더 걸리게 되어, 완벽한 타이밍을 확신할 수는 없다.
try {
Thread.sleep(2000); //2000밀리초 == 2초
} catch (InterruptedException ex) {
ex.printStackTrace();
}
스레드 병행성 (concurrency) 문제 : 객체의 락을 이용하여 해결
모든 자바 객체에는 자물쇠(락)가 하나씩 있다.
대부분 이 자물쇠는 열려 있으나, 멀티 스레드 환경에서 synchronized 메소드가 정의 되어 있다면 의미를 갖는다.
여러 스레드 중, 어느 하나가 synchronized 메소드를 만나면, 이 유일한 락을 가진 하나의 스레드만이 메소드 안에 들어갈 수 있다.
synchronized 방법 1 : 함수 전체를 동기화 하는 방법
public synchronized void increment() {
int i = balance; //balance 멤버 변수를 i로 대입
~~
//여기서 sleep 해도, synchronized 이기에 안전하다.
~~
balance = i + 1;
}
synchronized 방법 2 : 필요한 곳만 동기화 하는 방법
public void increment() {
synchronized(this) {
int i = balance;
~~
balance = i + 1;
}
}
스레드 교착상태(dead lock) 문제
두 스레드가 서로 상대의 락을 요구하며, 계속 기다리는 상태
A 스레드 : foo 락 (실행 가능 상태)
B 스레드 : bar 락 (실행 상태)
B 스레드 : bar 락 + foo 락 요구 (봉쇄 상태)
A 스레드 : foo 락 (실행 상태)
A 스레드 : foo 락 + bar 락 요구 (봉쇄 상태)
DB는 설정 시간 동안 반응이 없으면 트랜잭션 롤백을 해서 해결하지만, 자바는 처리 메커니즘이 없다.
'프로그래밍' 카테고리의 다른 글
[JAVA] 17. 코드를 배포합시다 (패키지 제작과 배포) (1) | 2024.06.04 |
---|---|
[JAVA] 16. 자료구조 (컬렉션 및 제네릭) (1) | 2024.06.04 |
[JAVA] 14. 객체 저장 (직렬화와 입출력) (0) | 2024.06.03 |
[JAVA] 13. 스윙을 알아봅시다 (레이아웃 관리와 구성요소) (2) | 2024.05.30 |
[JAVA] 12. 그래픽 이야기 (GUI, 이벤트 처리, 내부 클래스에 대한 소개) (1) | 2024.05.28 |