본문 바로가기
캠퍼스/Java

61. 스레드

by Sylar 2022. 8. 23.

 

Thread.sleep(1000); 단위는 ms, 딜레이를 준다 

 

 

위에 클래스에 메서드 하나 집어놓고 내용은 똑같이.

 

 

이렇게 하면 동기적인 프로그램이 된다. ( 하나 다 처리하고 이후에 남은거 처리 )

 

데이터 관점에서 동기적이라는건 데이터의 일관성을 의미한다

프로그램의 관점에서 동기적이라는건 일의 순서가 있다는 뜻.

 

1번 프로그램 실행 시키면 그거 끝날때 까지 기다린 후 끝나면 2번한테 시킴 ( 값을 리턴받고 난 이후 다른 행동 가능 )

이렇게 짜면 프로그램이 짜기 쉬워짐. 동기적인 프로그램은 코드가 내려가는대로 쭉쭉 실행시키면 끝이기 때문.

비동기적 프로그램은 실행시 코드는 점점 내려가다가 리턴값이 오면,

그 값을 받아야 하는 코드로 갔다가 멈춘 부분에서 다시 시작해야함. ( 일의 순서가 없다 )

여러가지 처리를 해야할때 쓰레드를 늘리는거 보다 단일쓰레드가 더 빠름 

 

타겟을 넣어줘야함. Runnable을 implements 해야 함.

 

 

서로 번갈아가면서 출력되는 모습.

이걸 전 포스팅에서 보여줬던 유사 채팅 프로그램에 적용시켜서,

진짜 채팅 프로그램 처럼 서로 대화를 주고 받을 예정이다.

 

 

메세지를 받는 부분을 그대로 복사해서 스레드에 넣었다.

하지만 이 안에는 BufferedReader 가 없어서 br이 정의되지 않아 에러가 남.

 

 

BufferedReader를 전역 변수로 만들었다.

 

프로토콜을 지우고 단순히 주고받는걸로 바꿈.

이후에 추가해줘야 할 부분이 서버는 받는 역할만 했기 때문에 쓰는 것도 추가해야 한다.

즉 BufferedReader 도 추가해야한다는 소리.

 

 

이렇게 추가한 후에 

 

bw, br은 전이중, keyboard는 반이중, stateful 방식으로 짠거

 

BufferedReader가 읽어주고 BufferedWriter가 출력한다.

 

이런방식으로 서로 주고받을 예정.

 

 

상대방쪽 코드도 위와 같이 수정한다.

 

 

서로 주고받는 모습.

 

//클라이언트쪽

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class MyclientSocket {

	Socket socket;
	BufferedWriter bw;
	BufferedReader br, keyboard;

	class ReadThread implements Runnable {

		@Override
		public void run() {

			while (true) {
				try {
					String msg = br.readLine();
					System.out.println("받은 메세지 :" + msg);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void init() {
		try {
			socket = new Socket("localhost", 10000);

			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

			// 읽기 쓰레드는 읽기만 한다.
			keyboard = new BufferedReader(new InputStreamReader(System.in));

			Thread t1 = new Thread(new ReadThread());
			t1.start();

			// 메인쓰레드 쓰기만 함.
			while (true) {
				String keyboardMsg = keyboard.readLine();
				bw.write(keyboardMsg + "\n");
				bw.flush();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		MyclientSocket mc = new MyclientSocket();
		mc.init();

	}
}
//서버쪽

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

//쓰는거
public class MyServerSoket {

	ServerSocket serverSocket;
	BufferedReader br, keyboard;
	BufferedWriter bw;

	class ReadThread implements Runnable {

		@Override
		public void run() {
			try {
				while (true) {

					String msg = br.readLine();
					System.out.println("받은 메세지 :" + msg);

					if (msg.equals("사이코::bye")) {
						break;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void init() {
		System.out.println("서버 시작 ---------------");
		try {
			serverSocket = new ServerSocket(10000);

			Socket socket = serverSocket.accept();

			System.out.println("클라이언트 연결 됨");

			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

			keyboard = new BufferedReader(new InputStreamReader(System.in));
			// 메인 스레드는 메세지 읽기만 함.
			Thread t1 = new Thread(new ReadThread());
			t1.start();

			// 메인 스레드는 메세지를 전송만 함
			while (true) {
				String keyboardMsg = keyboard.readLine();
				bw.write(keyboardMsg + "\n");
				bw.flush();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		MyServerSoket ms = new MyServerSoket();
		ms.init();
	}

}

'캠퍼스 > Java' 카테고리의 다른 글

62.JAVA 디자인 패턴  (1) 2022.09.26
60.gson  (0) 2022.08.23
59. 소켓통신  (0) 2022.08.23
58.Try, Catch  (0) 2022.08.23
57.DB와 JAVA 연결하기  (0) 2022.08.19