본문 바로가기
Programming Language/Java

쓰레드

by Ahngyuho 2025. 1. 7.

오늘은 쓰레드가 무엇이고, 왜 사용해야 하는지 알아보고 Java 에서는 쓰레드를 어떻게 사용할 수 있는지 간단히 문법을 알아보고 간단한 채팅 기능을 만들어 보겠습니다.

 

쓰레드란?

쓰레드는 프로그래머가 작성한 코드를 실행하는 역할을 하고, 모든 프로세스는 하나 이상의 쓰레드로 동작합니다.

하나의 프로세스가 다양한 기능을 동시에 수행해야 할 때, 각 기능을 쓰레드를 통해 실행시키면 됩니다.

 

채팅을 예를 들면, 채팅을 작성하는 기능과 다른 사용자들이 보낸 채팅을 보는 기능을 서로 각각 다른 쓰레드로 동작시켜 채팅을 실시간으로 보고/작성할 수 있습니다.

 

Java Thread 생성 방법

Java 에서 Thread 를 생성하는 방법은 크게 2가지 입니다.

  1. Thread 클래스  상속
  2. Runnable 인터페이스 구현

 

Thread 클래스 상속

public class Main {
    public static void main(String[] args) {

        Thread01 thread01 = new Thread01();
        thread01.start();
        
    }
}

public class Thread01 extends Thread{
    @Override
    public void run() {
        while(true){
            System.out.println("스레드 01");
        }

    }

}

 

 

 

Runnable 인터페이스 구현

public class Main {
    public static void main(String[] args) {

        Runnable runnable = new Thread03();
        Thread thread03 = new Thread(runnable);
        thread03.start();
    }
}



public class Thread03 implements Runnable{
    @Override
    public void run() {
        while(true){
            System.out.println("스레드 03");
        }
    }
}

 

이제 어떻게 만들어야 하는지는 알았으니 바로 적용해 봅시다.

 

채팅과 쓰레드

우선 채팅 프로그램의 특징을 살펴보면 

  • 채팅 작성
  • 채팅 조회

이렇게 되어있습니다. 글을 작성하는 도중에 글을 같이 조회할 수 있어야 하기 때문에 작성과 조회 기능을 쓰레드로 만들어서 실행시켜야 합니다.

 

채팅 조회 스레드

public class ReadThread extends Thread {
    Socket socket;
    public ReadThread(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream())
            );
            while (true) {
                // 데이터를 받는 코드
                System.out.println(in.readLine());
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

채팅 작성 스레드


public class WriteThread extends Thread {
    Socket socket;
    public WriteThread(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            String input;
            Scanner sc = new Scanner(System.in);
            while (true) {
                System.out.print("보낼 메시지 입력 : ");
                input = sc.nextLine();
                // 데이터를 보내는 코드
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                out.println(input);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 

클라이언트 서버 코드 

public class ThreadClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost", 1234);  // 서버와 연결 정보를 저장하고 있는 객체

            WriteThread writeThread = new WriteThread(socket);
            writeThread.start();

            ReadThread readThread = new ReadThread(socket);
            readThread.start();

            while (true) {}

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}


public class ThreadServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(1234); // 1
            Socket socket = serverSocket.accept(); // 2

            ReadThread readThread = new ReadThread(socket);
            readThread.start();

            WriteThread writeThread = new WriteThread(socket);
            writeThread.start();

            while (true) {}


        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

결과

 

 

 

Thread 의 start 메서드는 비동기로 실행되는 함수 입니다.

각 Thread의 start 메서드가 실행되면 Thread에 정의해둔 run 메서드가 비동기로 실행됩니다.

 

 

 

 

 

이 각각의 run 메서드가 독립적으로 각각 실행되며 동시에 실행되는 것과 같은 효과를 볼 수 있습니다.