국비 16일차_1

강지수·2024년 1월 5일
0

국비교육

목록 보기
30/97

지난 시간 복습

bx.setData(1000);

위 처럼 data를 넣는 방법을 '캡슐화' 라고 한다.


Thread 관련 글

Thread 관련 메서드가 죄다 Deprecated 된 이유

쓰레드를 잠시 멈추거나 재개하고 싶을때, 정말 쉽사리 많이쓰던 메서드는 stop(), suspend(), resume()이다. 다만 이 메서드들은 현재 deprecated되어서 사용이 권장되지 않는다

쓰레드를 이용한 복잡한 동시성 프로그램을 파악가능하고 완벽하게 만들기에는 거의 불가능에 가깝다는게 여러사람의 말이다

스칼라에서도 마찬가지 개념이 전반적으로 깔려있지만, 쓰레드의 메서드가 deprecated된 이유는 자명하다. 안전하지 않기 때문이다. 그 전에 쓰레드의 개념에 대해 알 필요가 있다.

...후략...

어제 내가 'CarRace' 클래스에서 초기화 시키는 과정 중 thread 동작 중 초기화버튼을 사용하면 thread가 멈추지 않고 이미지만 초기화시킨다고 질문했었는데, 이에 대한 대답을 준비하시며 가져온 글인 것 같다.


가운데 줄 그어진 의미가 deprecated 되었다는 의미.
사용할 순 있지만 권장하진 않는다는 뜻.


멈춤버튼을 누르면 suspend가 실행되며 멈추고 flag=false, 다시 멈춤을 누르면 resume이 실행되어 재실행되고 flag=true 로 바뀐다.


Join method 사용 전


Join method 사용

threadAction.join();

threadAction이 종료될 때까지 다음 내용은 대기


thread 는 기본적으로 무작위로 실행된다 (cpu를 먼저 점유한 것 부터 실행)

하지만 순차적으로 진행하게 하고 싶을 때 동기화를 사용한다.(synchronized)

동기화 전


package com.tech.gt009.music;

public class MusicBoxTest {
	public static void main(String[] args) {
		MusicBox box=new MusicBox();
		MusicPlayer kim1=new MusicPlayer(1,box);
		MusicPlayer kim2=new MusicPlayer(2,box);
		MusicPlayer kim3=new MusicPlayer(3,box);
		
		System.out.println(Thread.currentThread().getName());
		System.out.println(Thread.currentThread().getThreadGroup());
		System.out.println(Thread.currentThread().getId());
		System.out.println(Thread.currentThread().getPriority());
		kim1.start();
		kim2.start();
		kim3.start();
	}
}

MusicBoxTest.java


package com.tech.gt009.music;

public class MusicBox {
//	동기화
	public synchronized void playMusicA() {
		for (int i = 0; i < 10; i++) {
			System.out.println("가요플레이"+i);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public synchronized void playMusicB() {
		for (int i = 0; i < 10; i++) {
			System.out.println("팝송플레이"+i);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public synchronized void playMusicC() {
		for (int i = 0; i < 10; i++) {
			System.out.println("힙합플레이"+i);
			try {
				Thread.sleep((int)(Math.random()*1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

MusicBox.java


package com.tech.gt009.music;

public class MusicPlayer extends Thread{
	int type;
	MusicBox musicBox;
	public MusicPlayer(int type,MusicBox musicBox) {
		this.type=type;
		this.musicBox=musicBox;
	}
	@Override
	public void run() {
		switch (type) {
		case 1:
			musicBox.playMusicA();
			Thread.currentThread().setPriority(9);
			break;
		case 2:
			musicBox.playMusicB();
//			Thread.currentThread().setPriority(9);
			break;
		case 3:
			musicBox.playMusicC();
//			Thread.currentThread().setPriority(9);
			break;

		default:
			break;
		}
	}
}

MusicPlayer.java

동기화 후


Priority 는 1~10 까지 있고, 1이 MINPriority, 5가 NORMALPriority, 10이 MAXPriority 이며, 숫자가 높을 수록 우선순위가 높다.

이것은 확률이기때문에 무조건적으로 먼저 나오는 것은 아니다.


package com.tech.gt009.music;

public class ThreadPractice {
	public static void main(String[] args) {
		ThreadPractice tp=new ThreadPractice();
	}
	public ThreadPractice() {
		MyThread t1=new MyThread("FirstThread");
		MyThread t2=new MyThread("SecondThread");
		MyThread t3=new MyThread("ThirdThread");
		
		t1.setPriority(10);
		t2.setPriority(5);
		t3.setPriority(1);
		
		t1.start();
		t2.start();
		t3.start();
	}
	
	static class MyThread extends Thread{
		String name;
		
		public MyThread(String name) {
			this.name=name;
		}

		@Override
		public void run() {
			int second=0;
			while (true) {
				second++;
				System.out.println(second+"-"+name);
				
				try {
					Thread.sleep(1000);					
				} catch (Exception e) {
					// TODO: handle exception
					e.printStackTrace();
				}
			}
		}
	}
}

결과

1-FirstThread
1-ThirdThread
1-SecondThread
2-FirstThread
2-ThirdThread
2-SecondThread
3-SecondThread
3-ThirdThread
3-FirstThread
4-ThirdThread
4-SecondThread
4-FirstThread
5-ThirdThread
5-SecondThread
5-FirstThread
6-ThirdThread
6-SecondThread
6-FirstThread
7-ThirdThread
7-SecondThread
7-FirstThread
8-ThirdThread
8-SecondThread
8-FirstThread
9-ThirdThread
9-SecondThread
9-FirstThread
10-ThirdThread
10-SecondThread
10-FirstThread
11-ThirdThread
11-SecondThread
11-FirstThread
12-ThirdThread
12-SecondThread
12-FirstThread
13-ThirdThread
13-SecondThread
13-FirstThread
14-ThirdThread
14-SecondThread
14-FirstThread
15-ThirdThread
15-SecondThread
15-FirstThread
16-ThirdThread
16-SecondThread
16-FirstThread
17-ThirdThread
17-SecondThread
17-FirstThread
18-ThirdThread
18-SecondThread
18-FirstThread
19-ThirdThread
19-SecondThread
19-FirstThread
20-ThirdThread
20-SecondThread
20-FirstThread

우선순위를 설정해두어도 확률을 높이는 것뿐이기 때문에 무조건 우선적으로 나오지 않고 random 인 점은 동일하다.


네트워크 프로그래밍

서버는 성능이 좋아야 함.
클라이언트가 한 둘이 아니고, 동시접속건수도 얼마가 될 지 모르기 때문에
capa가 높아야 함.
또한 24시간 365일 켜져 있어야 하기 때문에 안정성이 뛰어나야 함.

URL의 구조
프로토콜 / 호스트 이름 / 파일 이름 / 포트번호

http의 포트번호는 80으로 정해져있음.

  1. (서버가 켜져 있는 상태)
  2. 클라이언트에서의 서버로의 연결 요청 (포트를 통해)
  3. 클라이언트에서 소켓이 생성됨
  4. 서버에서 소켓이 생성됨
  5. 클라이언트에서 서버로의 출력 스트림이 전달됨
  6. 서버에서 클라이언트로의 입력 스트림이 전달됨


레이어 7계층

OSI 7계층 : 네트워크에서 통신이 일어나는 과정을 7단계로 나눈 것

  1. 물리적 계층 (Physical Layer)
  2. 데이터 링크계층 (Data Ling Layer)
  3. 네트워크 계층 (Network Layer)
  4. 전송 계층 (Transport Layer)
  5. 세션 계층 (Session Layer)
  6. 표현 계층 (Presentation Layer)
  7. 응용 계층 (Application Layer)

계층 별 Protocol

더 깊은 내용은 기사공부할 때 필요함.
현재는 이런 계층으로 나뉘어져 있고, protocol 이 분류되는구나 정도만 알고 넘어가면 됨.


iana

https://www.iana.org/

포트 num 은 0~65535 까지 있고, 몇몇은 이미 정해져 있어서 사용할 수 없다.
ex) 0~1023 은 system port로 user가 사용하면 안된다.

http, www 는 80번 포트로 정해져 있다.


package com.tech.gt009.sock;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerClass {
	public static void main(String[] args) throws IOException {
		ServerSocket ss=new ServerSocket(5005);
		System.out.println("서버준비");
		try {
			while (true) {
				Socket socket=ss.accept();
				
				try {
				PrintWriter out=new PrintWriter(socket.getOutputStream(),true);
				out.println("홍길동");
				} catch (Exception e) {
					
					e.printStackTrace();
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
		}finally {
			System.out.println("서버종료");
			ss.close();
		}
	}

}

ServerClass.java


package com.tech.gt009.sock;

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

public class ClientClass {
	public static void main(String[] args) throws UnknownHostException, IOException{
		Socket s=new Socket("172.16.4.16",5005);
		BufferedReader input=
				new BufferedReader(new InputStreamReader(s.getInputStream()));
		String res=input.readLine();
		System.out.println("응답내용:"+res);
		System.exit(0); // 강제 종료
	}

}

ClientClass.java


서버클래스를 실행해서 서버가 열리고, 서버가 열린 후 클라이언트클래스를 실행하면 응답내용이 출력된다.


package com.tech.gt010.chat;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ChatClient extends Frame implements ActionListener,Runnable{
	Button btn_exit; // 종료
	Button btn_send; // 전송
	Button btn_connect; // 서버 접속
	
	TextArea txt_list; // 채팅 내용
	TextField txt_server_ip; // ip
	TextField txt_name; // 대화명
	TextField txt_input; // 채팅내용
	
	Socket client;
	BufferedReader br; // 입력 객체
	PrintWriter pw; // 출력 객체
	
	String server_ip; // 서버 ip 텍스트
	final int port=5005; // 포트번호
	CardLayout cl; // 카드 레이아웃
	
	public ChatClient() {
//		화면구성
		setTitle("채팅 클라이언트 ver1.1");
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				dispose(); // 자원 반납 후 프레임 닫기
			}
		});
		
		cl=new CardLayout();
		setLayout(cl);
		
//		접속화면구성
		Panel connect=new Panel(); // 접속화면판넬
		connect.setBackground(Color.LIGHT_GRAY);
		connect.setLayout(new BorderLayout());
		
		btn_connect=new Button("서버접속");
		btn_connect.addActionListener(this);
		
		txt_server_ip=new TextField("172.16.4.16",15);
		txt_name=new TextField("홍길동",15);
		
		Panel connect_sub=new Panel(); // 접속창의 서브판넬
		connect_sub.add(new Label("서버아이피(IP) : "));
		connect_sub.add(txt_server_ip);
		connect_sub.add(new Label("대화명 : "));
		connect_sub.add(txt_name);
		
//		채팅판넬구성
		Panel chat=new Panel();
		chat.setLayout(new BorderLayout());
		Label lblChat=new Label("채팅접속화면",Label.CENTER);
		
		connect.add(lblChat,BorderLayout.NORTH);
		connect.add(connect_sub,BorderLayout.CENTER);
		connect.add(btn_connect,BorderLayout.SOUTH);
		
//		채팅창화면구성
		txt_list=new TextArea(); // 채팅내용을 보여줌
		
		txt_input=new TextField("",25); // 채팅입력
		btn_exit=new Button("종료");
		btn_send=new Button("전송");
		
		btn_exit.addActionListener(this);
		btn_send.addActionListener(this);
		txt_input.addActionListener(this);
		
//		채팅창하위판넬구성
		Panel chat_sub=new Panel();
		chat_sub.add(txt_input);
		chat_sub.add(btn_send);
		chat_sub.add(btn_exit);
		
		Label lblChatTitle=new Label("채팅프로그램ver 1.1",Label.CENTER);
		chat.add(lblChatTitle,BorderLayout.NORTH);
		chat.add(txt_list,BorderLayout.CENTER);
		chat.add(chat_sub,BorderLayout.SOUTH);
		
		add(connect,"접속창");
		add(chat,"채팅창");
		
		cl.show(this, "점속창");
		setBounds(250,250,300,300);
		setVisible(true);
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
	}

	public static void main(String[] args) {
		new ChatClient();
	}
}

채팅창 만드는 중
오후에 이어서 만들 예정


profile
개발자 준비의 준비준비중..

0개의 댓글