Java 웹 개발

21.09.17 - 웹 개발 입문 28일차

개발이란 2021. 9. 17. 22:16

- 27일차 과제 풀이

 

Client 접속 시 "로또 번호 6개"를 Client에게 전송하는 서버
= 로또 번호 6개의 자료형은 다음과 같이 분석해볼 수 있다.
-> int 6개 : 멀티바이트 출력
-> int[] 1개 : 객체 출력
-> List<Integer> 1개 : 객체 출력
-> Set<Integer> 1개 : 객체 출력
 -> 내가 만든 클래스 : 객체 출력

 

- 멀티 바이트로 구현

package api.net.tcp04;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class Server4 {
	public static void main(String[] args) throws IOException {

		ServerSocket server = new ServerSocket(30000);// 서버 30000포트 개방

		Socket socket = server.accept();// 사용자 접속 수락

		// 로또 번호 6개 추첨
		Random r = new Random();
		Set<Integer> lotto = new TreeSet<>();
		while (lotto.size() < 6) {
			lotto.add(r.nextInt(45) + 1);
		}

		// 사용자에게 로또번호 6개를 보내는 코드
		// --> int 6개를 보낼 수 있도록 멀티바이트 스트림을 구성
		OutputStream out = socket.getOutputStream();
		BufferedOutputStream buffer = new BufferedOutputStream(out);
		DataOutputStream data = new DataOutputStream(buffer);
		for (int number : lotto) {
			data.writeInt(number);
//			data.flush();//그때그때 바로 전송
		}

		data.flush();// 끝나고 한번에 전송
		socket.close();

		server.close();

	}
}

 

- 객체로 구현

package api.net.tcp04;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class Server5 {
	public static void main(String[] args) throws IOException {

		ServerSocket server = new ServerSocket(30000);// 서버 30000포트 개방

		Socket socket = server.accept();// 사용자 접속 수락

		// 로또 번호 6개 추첨
		Random r = new Random();
		Set<Integer> lotto = new TreeSet<>();
		while (lotto.size() < 6) {
			lotto.add(r.nextInt(45) + 1);
		}

		// 사용자에게 로또번호 6개를 보내는 코드
		// --> Set<Integer> 1개를 전송하도록 객체스트림을 구성
		OutputStream out = socket.getOutputStream();
		BufferedOutputStream buffer = new BufferedOutputStream(out);
		ObjectOutputStream oData = new ObjectOutputStream(buffer);

		oData.writeObject(lotto);

		socket.close();

		server.close();

	}
}

 

 

서버에서 전송되는 데이터(로또번호 6개)를 수신하여 출력
= 서버에서 보내는 형태에 맞게 수신을 해야 한다.
--> 서버에서 멀티바이트로 전송하면 멀티바이트 수신을 해야한다
--> 서버에서 객체로 전송하면 객체 수신을 해야한다

package api.net.tcp04;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client3 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 30000);

		// 서버에서 전송되는 데이터(로또번호 6개)를 수신하여 출력
		// = 멀티바이트 수신코드
		InputStream in = socket.getInputStream();
		BufferedInputStream buffer = new BufferedInputStream(in);
		DataInputStream data = new DataInputStream(buffer);

		try {
			while (true) {
				int number = data.readInt();
				System.out.println("로또번호 : " + number);
			}
		} catch (EOFException e) {
			System.out.println("읽기 완료");
		}

		socket.close();
	}
}

 

 

 

네트워크 - 문자열 데이터 전송

- 발신을 위한 스트림 구성

package api.net.tcp05;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(30000);

		Socket socket = server.accept();

		//데이터 준비
		String str = "어서와 Java는 처음이지";

		//출력스트림 준비
		//= socket에는 outputstream/inputstream밖에 없다
		//= writer/reader 계열을 사용하고 싶다면 "변환"이 필요
		//= 이 역할을 수행하는 클래스가 OutputStreamWriter/InputStreamReader
		OutputStream out = socket.getOutputStream();
		OutputStreamWriter converter = new OutputStreamWriter(out);
		BufferedWriter buffer = new BufferedWriter(converter);
		PrintWriter printer = new PrintWriter(buffer);

		printer.println(str);
		printer.flush();
		System.out.println("전송 완료");

		socket.close();

		server.close();

	}
}

 

 

- 수신을 위한 스트림 구성

package api.net.tcp05;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 30000);

//		InputStream in = socket.getInputStream();
//		InputStreamReader converter = new InputStreamReader(in);
//		BufferedReader buffer = new BufferedReader(converter);

//		InputStreamReader converter = new InputStreamReader(socket.getInputStream());
//		BufferedReader buffer = new BufferedReader(converter);

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

		String str = buffer.readLine();
		System.out.println("str = " + str);

		socket.close();
	}
}

 

 

네트워크 - 문자열 전송 프로그램

Q. TCP 통신을 이용하여 클라이언트가 서버에 접속하도록 구현하시고 다음 요구사항에 맞게 코드를 구현하세요
- 클라이언트에서는 `Scanner`를 이용하여 사용자가 메세지를 입력합니다.
- 입력한 메세지는 socket을 이용하여 서버에 전송됩니다.
- 서버에서는 수신한 메세지를 화면에 출력합니다.
- 만약 클라이언트에서 사용자가 `종료`를 입력하면 더이상의 전송을 중지하고 연결을 종료합니다.

 

- 출력

package api.net.tcp06;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server3 {
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(30000);
		Socket socket = server.accept();

		// 사용자가 지속적으로 보내는 문자열 데이터를 받아서 출력하는 코드
		InputStream in = socket.getInputStream();
		InputStreamReader converter = new InputStreamReader(in);
		BufferedReader buffer = new BufferedReader(converter);

		while (true) {
			String line = buffer.readLine();
			if (line.equals("종료"))
				break;
			System.out.println("수신 : " + line);
		}

		socket.close();
		server.close();
	}
}

 

- 입력

package api.net.tcp06;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client3 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 30000);

		// 키보드 입력도구
		Scanner sc = new Scanner(System.in);
		// 네트워크 출력스트림
		OutputStream out = socket.getOutputStream();
		OutputStreamWriter converter = new OutputStreamWriter(out);
		BufferedWriter buffer = new BufferedWriter(converter);
		PrintWriter printer = new PrintWriter(buffer);

		while (true) {
			System.out.print("입력 : ");
			String line = sc.nextLine();

			printer.println(line);
			printer.flush();

			if (line.equals("종료"))
				break;
		}

		sc.close();
		socket.close();
	}
}

입력 : 자바
입력 : 헬로우
입력 : 종료

 

수신 : 자바
수신 : 헬로우

 

 

 

네트워크 - 문자열 에코서버

목표 : 에코 서버(Echo server). 사용자가 보낸 메세지를 그대로 반환하는 서버

수신(입력)과 발신(출력)을 위한 스트림을 모두 준비해야 한다.
= 수신후 바로 전송이 가능

 

- 서버

package api.net.tcp07;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) throws IOException {

		ServerSocket server = new ServerSocket(30000);

		Socket socket = server.accept();

//		수신용 스트림
		InputStream in = socket.getInputStream();
		InputStreamReader inConverter = new InputStreamReader(in);
		BufferedReader inBuffer = new BufferedReader(inConverter);

//		발신용 스트림
		OutputStream out = socket.getOutputStream();
		OutputStreamWriter outConverter = new OutputStreamWriter(out);
		BufferedWriter outBuffer = new BufferedWriter(outConverter);
		PrintWriter printer = new PrintWriter(outBuffer);

//		메세지 수신 후 바로 발신
		String line = inBuffer.readLine();
		printer.println(line);
		printer.flush();

		socket.close();

		server.close();

	}
}

 

- 사용자

package api.net.tcp07;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket = new Socket("localhost", 30000);

//		수신용 스트림
		InputStream in = socket.getInputStream();
		InputStreamReader inConverter = new InputStreamReader(in);
		BufferedReader inBuffer = new BufferedReader(inConverter);

//		발신용 스트림
		OutputStream out = socket.getOutputStream();
		OutputStreamWriter outConverter = new OutputStreamWriter(out);
		BufferedWriter outBuffer = new BufferedWriter(outConverter);
		PrintWriter printer = new PrintWriter(outBuffer);

		String text = "Hello Java!";
		printer.println(text);
		printer.flush();

		String line = inBuffer.readLine();
		System.out.println("회신 : " + line);

		socket.close();
	}
}

회신 : Hello Java!

 

 

 

Q. 다음 요구사항에 맞게 `챗봇 서버`와 `챗봇 클라이언트`를 구현하시기 바랍니다
- 챗봇 서버(ChatbotServer) 클래스
- 1개의 클라이언트 접속을 받아 지속적으로 채팅에 답변을 하도록 구현
- 질문에 대한 답변은 다음 내용만 가능
- 질문 : $동기부여, 답변 : 넌 언제가 지구최강의 개발자가 될거야!
- 질문 : $링크, 답변 : 문서 사이트는 https://hiphop5782.github.io 입니다.
- 질문 : $화이팅, 답변 : 우리모두 화이팅!
- 질문과 일치하지 않는 채팅은 답변이 없는 것으로 간주하여 "답변이 준비되지 않았습니다" 전송 
- 사용자에게서 `exit`라는 메세지가 수신될 경우 사용자의 연결을 종료
- 챗봇 클라이언트(ChatbotClient) 클래스
- 서버에 접속한 뒤 사용자의 채팅을 입력받아 서버로 전송한 뒤 답변을 수신하여 화면에 출력하도록 구현
- 사용자가 `exit`를 입력할 경우 서버로 종료메세지를 전송한 뒤 프로그램 종료

 

- 서버 구현 방법 (1) - 기본

package api.net.tcp08;

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

public class ChatbotServer {
	public static void main(String[] args) throws IOException {
//		서버 준비
		ServerSocket server = new ServerSocket(30000);

//		사용자 접속
		Socket socket = server.accept();

//		입력 및 출력 스트림 생성
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

		while(true) {
			//사용자 메세지 수신
			String line = reader.readLine();

			//사용자가 강제로 종료하면 line == null 수신
			if(line == null || line.equals("exit")) {
				break;
			}
//			printer.println(line);
			switch(line) {
			case "$동기부여":	printer.println("넌 언젠가 지구최강의 개발자가 될거야!"); break;
			case "$화이팅":		printer.println("우리모두 화이팅!"); break;
			case "$링크":			printer.println("https://www.naver.com/"); break;
			default: 				printer.println("지원하지 않는 명령입니다"); break;
			}
			printer.flush();
		}

//		사용자 접속 종료
		socket.close();

//		서버 종료
		server.close();
	}
}

 

- 서버 구현 방법 (2) - 출력 구문 통일

package api.net.tcp08;

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

public class ChatbotServer2 {
	public static void main(String[] args) throws IOException {
//		서버 준비
		ServerSocket server = new ServerSocket(30000);

//		사용자 접속
		Socket socket = server.accept();

//		입력 및 출력 스트림 생성
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

		while(true) {
			//사용자 메세지 수신
			String line = reader.readLine();

			//사용자가 강제로 종료하면 line == null 수신
			if(line == null || line.equals("exit")) {
				break;
			}

			String text;
			switch(line) {
			case "$동기부여":	text = "넌 언젠가 지구최강의 개발자가 될거야!"; break;
			case "$화이팅":		text = "우리모두 화이팅!"; break;
			case "$링크":			text = "문서 사이트는 https://www.naver.com/ 입니다"; break;
			default: 				text = "지원하지 않는 명령입니다"; break;
			}

			printer.println(text);
			printer.flush();
		}

//		사용자 접속 종료
		socket.close();

//		서버 종료
		server.close();
	}
}

 

- 서버 구현 방법 (3) - 메세지별 응답을 Collection으로 정의한다.

package api.net.tcp08;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class ChatbotServer3 {
	public static void main(String[] args) throws IOException {

		Map<String, String> messages = new HashMap<>();
		messages.put("$화이팅", "우리모두 화이팅!");
		messages.put("$동기부여", "넌 언젠가 지구최강의 개발자가 될거야!");
		messages.put("$링크", "문서 사이트는 https://www.naver.com 입니다");

//		서버 준비
		ServerSocket server = new ServerSocket(30000);

//		사용자 접속
		Socket socket = server.accept();

//		입력 및 출력 스트림 생성
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

		while(true) {
			//사용자 메세지 수신
			String line = reader.readLine();

			//사용자가 강제로 종료하면 line == null 수신
			if(line == null || line.equals("exit")) {
				break;
			}

			//명령에 대한 응답을 messages에서 찾는다(없으면 null이 나온다)
			String text = messages.get(line);
			if(text == null) {
				printer.println("지원하지 않는 명령입니다");
			}
			else {
				printer.println(text);
			}
			printer.flush();
		}

//		사용자 접속 종료
		socket.close();

//		서버 종료
		server.close();
	}
}

 

- 사용자

package api.net.tcp08;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ChatbotClient {
	public static void main(String[] args) throws IOException{
//		연결 생성
		Socket socket = new Socket("localhost", 30000);

//		입력 및 출력 스트림 생성
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
		Scanner sc = new Scanner(System.in);

		while(true) {
			System.out.print("명령 : ");
			String input = sc.nextLine();//키보드 입력
			printer.println(input);//메세지 출력
			printer.flush();

			if(input.equals("exit")) break;//exit 입력 시 서버에게 알린 후 응답 수신하지 말고 종료

			String response = reader.readLine();//응답 수신
			System.out.println("<서버응답>");
			System.out.println(response);
		}
		sc.close();
//		연결 종료
		socket.close();
	}
}

명령 : 안녕
<서버응답>
지원하지 않는 명령입니다
명령 : $링크
<서버응답>
문서 사이트는 https://www.naver.com/ 
명령 : exit 

 

 

 

- 추가

명령을 이용하여 응답을 생성하는 메소드로 구현하기 (CommandFactrory)

package api.net.tcp08;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

public class ChatbotServer4 {
	public static void main(String[] args) throws IOException {
//		서버 준비
		ServerSocket server = new ServerSocket(30000);

//		사용자 접속
		Socket socket = server.accept();

//		입력 및 출력 스트림 생성
		BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

		while (true) {
			// 사용자 메세지 수신
			String line = reader.readLine();

			// 사용자가 강제로 종료하면 line == null 수신
			if (line == null || line.equals("exit")) {
				break;
			}

			// 명령에 대한 응답을 CommandFactory에서 찾는다
			String text = CommandFactory.create(line);
			printer.println(text);
			printer.flush();
		}

//		사용자 접속 종료
		socket.close();

//		서버 종료
		server.close();
	}
}

 

- CommandFactrory

package api.net.tcp08;

public class CommandFactory {

	//명령을 이용하여 응답을 생성하는 메소드
	public static String create(String command) {
		switch(command) {
		case "$동기부여": return "넌 언젠가 지구최강의 개발자가 될거야!";
		case "$화이팅": return "우리모두 화이팅!";
		case "$링크": return "문서 사이트는 https://www.naver.com/ 입니다";
		default: return "지원하지 않는 명령입니다";
		}
	}
}

 

 

 

스레드

싱글 스레드 vs 멀티 스레드 (cf : 프로세스)
= 프로세스는 실행중인 프로그램을 의미한다.
= 즉, 프로그램을 실행하면 프로세스가 생성된다고 볼 수 있다.
= 스레드는 프로세스에서 여러 개의 작업을 동시에 실행하기 위해 생성하는 작업 수행 단위
= 프로세스가 회사면 스레드는 작업자와 같다.
= 프로세스에는 무조건 1개의 스레드가 존재하며, 필요하다면 더 생성할 수 있다.
= 싱글 스레드는 스레드가 한 개인 경우를 말하며, 멀티 스레드는 추가로 스레드를 생성한 경우를 말한다.
= 자바는 실행하면 main이라는 이름의 스레드가 기본적으로 생성된다.
= 스레드는 동시에 1개의 작업을 수행할 수 있다.

 

 

싱글 스레드에서 여러 개의 작업을 처리해보기
1. 사용자에게 입력창을 보여주고 입력을 받는 작업
2. 1초 간격으로 1부터 100까지 출력하는 작업

package api.thread;

import javax.swing.JOptionPane;

public class Test02 {
	public static void main(String[] args) throws InterruptedException {

		// 1
		String input = JOptionPane.showInputDialog("메세지 입력");
		System.out.println(input);

		// 2
		for (int i = 1; i <= 100; i++) {
			System.out.println(i);
			Thread.sleep(1000L);
		}
	}
}

--> 블럭킹으로 인해 1번 메세지 입력을 안하면 2번 작업을 안한다

 

 

멀티스레드

스레드를 하나 생성해서 main 과 병렬로 실행
= main에서 1부터 100까지 출력하는 코드를 실행
= 생성한 스레드에서 입력 코드를 실행

package api.thread;

import javax.swing.JOptionPane;

public class Test03 {
	public static void main(String[] args) throws InterruptedException {

		// 스레드(일꾼) 생성
		// Thread t = new Thread();//이렇게 생성하면 뭘 해야하는지 알 수 없다.
		Thread t = new Thread() {// 익명클래스를 만들어서 작업을 run메소드에 재정의한다.
			@Override
			public void run() {
				// 2
				for (int i = 1; i <= 100; i++) {
					System.out.println(i);
					try {
						Thread.sleep(1000L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};

		// 스레드(일꾼) 구동
		t.start();

		// 1
		String input = JOptionPane.showInputDialog("메세지 입력");
		System.out.println(input);
	}
}

--> main이 끝나도 생성한 스레드의 작업은 멈추지 않고 진행된다.

 

스레드의 문제점
= main이 끝났을 때 스레드를 종료할것인가 종료하지 않을 것인가 결정을 해야 한다.
= 스레드에게 작업을 지시하기 전에 미리 약속을 해놔야 한다.
= 한 번 일을 시작하면 강제로 중지시키기가 매우 어렵다.

 

-> 데몬 스레드 생성으로 해결

package api.thread;

import javax.swing.JOptionPane;

public class Test04 {
	public static void main(String[] args) throws InterruptedException {

		Thread t = new Thread() {// 익명클래스를 만들어서 작업을 run메소드에 재정의한다.
			@Override
			public void run() {
				// 2
				for (int i = 1; i <= 100; i++) {
					System.out.println(i);
					try {
						Thread.sleep(1000L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};

		// 이 지점에서 스레드에 필요한 모든 설정을 완료해야 한다.
		// = 구동을 시작하면 통제할 수 없기 때문

		t.setDaemon(true);

		// 스레드(일꾼) 구동
		t.start();

		// 1
		String input = JOptionPane.showInputDialog("메세지 입력");
		System.out.println(input);
	}
}

데몬 스레드 설정(main에 완전한 종속이 이루어진다)
= 모든 스레드가 데몬인 경우에만 종속이 이루어진다
= 단 한 개라도 데몬 스레드가 아닌 스레드가 생성되었다면 모든 데몬 스레드가 작동하지 않는다.
= 다 데몬하든가 아니면 다 하지말든가 중간은 없다.

 

 

스레드를 생성하는 다른 방법
= Runnable 인터페이스의 객체를 만들어서 작업 내용을 보관
= Ruunable 인터페이스를 이용하여 Thread를 생성

package api.thread;

import javax.swing.JOptionPane;

public class Test05 {
	public static void main(String[] args) throws InterruptedException {

		Runnable r = new Runnable() {
			@Override
			public void run() {
				// 2
				for (int i = 1; i <= 100; i++) {
					System.out.println(i);
					try {
						Thread.sleep(1000L);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};

		Thread t = new Thread(r);

		t.setDaemon(true);

		// 스레드(일꾼) 구동
		t.start();

		// 1
		String input = JOptionPane.showInputDialog("메세지 입력");
		System.out.println(input);
	}
}

 

 

- 함수형 인터페이스(@FunctionalInterface)는 람다(추론)식이 가능하다.

package api.thread;

import javax.swing.JOptionPane;

public class Test06 {
	public static void main(String[] args) throws InterruptedException {

		Runnable r = () -> {
			// 2
			for (int i = 1; i <= 100; i++) {
				System.out.println(i);
				try {
					Thread.sleep(1000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};

		Thread t = new Thread(r);

		t.setDaemon(true);

		// 스레드(일꾼) 구동
		t.start();

		// 1
		String input = JOptionPane.showInputDialog("메세지 입력");
		System.out.println(input);
	}
}

 

 

Q. 다음 작업을 처리할 수 있도록 스레드 환경을 구성하시오.
작업1 : 5초에 한번씩 콘솔에 `------------------------------` 출력(5번)
작업2 : 3초에 한번씩 콘솔에 `Hello` 출력(10번)
작업3 : 2초에 한번씩 콘솔에 `Java` 출력(15번)

package api.thread;

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

//		작업1 - thread(t1)
		Runnable r1 = () -> {
			for (int i = 0; i < 5; i++) {
				try {
					Thread.sleep(5000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("-----------------");
			}
		};
		Thread t1 = new Thread(r1);
		t1.setDaemon(true);
		t1.start();

//		작업2 - thread(t2)
		Runnable r2 = () -> {
			for (int i = 0; i < 10; i++) {
				try {
					Thread.sleep(3000L);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("Hello");
			}
		};
		Thread t2 = new Thread(r2);
		t2.setDaemon(true);
		t2.start();

//		작업3 - main thread
		for (int i = 0; i < 15; i++) {
			try {
				Thread.sleep(2000L);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("Java");
		}

	}
}

Java
Hello
Java
-----------------
Java
Hello
Java
Hello
-----------------
Java
Java
Hello
Java
-----------------
Hello
Java
Java
Hello
-----------------
Java
Hello
Java
Hello
Java
-----------------
Java
Hello
Java
Hello
Java