반응형
Thread
쓰레드가 없는 프로그램은 없고 단일 쓰레드를 사용하는 프로그램도 없다.
쓰레드는 cpu에 의해서 실행되어지는 실행 단위이다.
프로세스 VS 쓰레드
쓰레드는 프로세스안에서 일을 한다. 일 = cpu를 활용한다.
컨텍스트 스위칭 (문맥교환)
쓰레드는 램에 존재하고 있다가 번갈아 가면서 cpu에 올라가서 연산처리가 된 후 내려오는 것을 반복한다. cpu에 머무는 시간은 0.013초이다. 그래서 클럭수가 높을수록 성능이 좋은 컴퓨터이다.
스케줄링이라고 각 쓰레드에 사용 시간과 우선순위를 정해서 사용하게 된다.
java thread 작성 방법
1. Thread 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | public class base { public static void main(String[] args) { // TODO Auto-generated method stub // Thread 클래스 상속 받았을때 MyThread thread = new MyThread(); thread.start(); // Runnable 인터페이스를 상속 받았을때 Runnable r = new LineThread(); Thread linethread = new Thread(r); linethread.run(); while(true){ System.out.println("main"); Busy.waiting(); } } } class MyThread extends Thread{ // 실제 쓰레드가 수행할 작업들 public void run() { // TODO Auto-generated method stub super.run(); while(true){ System.out.println("MyThread"); Busy.waiting(); } } // 쓰레드 : 새로운 쓰레드 스택 생성 public synchronized void start() { // TODO Auto-generated method stub super.start(); } } class Busy{ // public static void waiting(){ for(int i=0; i<10000; i++){ for(int j=0;j<1000;j++){ j = j; } } } } |
2. Runnable 인터페이스
Runnable 인터페이스를 사용하면 상속도 가능하게 된다는 장점이 있다.
1 2 3 4 5 6 7 8 9 10 11 | public class LineThread implements Runnable { public void run() { for(;;){ System.out.println("____________________________"); Busy.waiting(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public class base { public static void main(String[] args) { WorkThread work = new WorkThread(); work.start(); while(true){ GlobalData.data--; System.out.println(GlobalData.data); Busy.waiting(); } } } class WorkThread extends Thread{ public void run() { // TODO Auto-generated method stub super.run(); for(;;){ GlobalData.data++; System.out.println(GlobalData.data); Busy.waiting(); } } } class GlobalData{ // 전역변수 공유 public static int data = 0; } class Busy{ // public static void waiting(){ for(int i=0; i<10000; i++){ for(int j=0;j<1000;j++){ j = j; } } } } |
Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.*; import java.util.*; public class Server { // Server를 추상화한 클래스 private int Port; private String ip; private ServerSocket serverSocket; private InetAddress addr; private ArrayList socketlist; // ArrayList말고 다른 방법 //1. 별도에 UserList //2. Thread public Server(int Port){ this.Port = Port; this.socketlist = new ArrayList(); } public void start(){ try { serverSocket = new ServerSocket(this.Port); while(true){ Socket clientsocket = serverSocket.accept(); socketlist.add(clientsocket); addr = clientsocket.getInetAddress(); System.out.println(addr.getHostAddress()+" 접속 인원"); /*for(int j=0;j<socketlist.size();j++){ // Socket client = (Socket)socketlist.get(j); if(client == clientsocket){ // 소켓비교 OutputStream out = client.getOutputStream(); PrintWriter pw = new PrintWriter(new OutputStreamWriter(out)); pw.println(addr.getHostName()+"님이 입장"); pw.flush(); } }*/ } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
Base - main을 따로 구현
1 2 3 4 5 6 7 8 9 10 | public class base { public static void main(String[] args) { Server server = new Server(10001); server.start(); } } |
동기화
- 어떤 행위, 순서를 맞추기 위한 동기화
- 데이터 동기화, 같은 생각을 하기 위함
Thread이용
클라이언트가 입력한 문자를 모든 클아이언트와 서버에 출력하는 소스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | import java.io.BufferedReader; 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.*; import java.util.ArrayList; public class ClientThread extends Thread { private Socket ClientSocket; // 현재 소켓 private ArrayList socketList; // 접속자 명단 private InputStream in; private OutputStream out; public ClientThread(Socket ClientSocket, ArrayList socketList) { this.ClientSocket = ClientSocket; this.socketList = socketList; try { // ClientSocket으로 부터 in, out 스트림 획득 this.in = ClientSocket.getInputStream(); this.out = ClientSocket.getOutputStream(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { super.run(); //PrintWriter pw = new PrintWriter(new OutputStreamWriter(this.out)); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String msg = null; // Echo Server try { //inputStream 읽어오기 while((msg = br.readLine()) != null){ //받은 내용 화면 출력 System.out.println("[ "+"받은 내용"+" ]"+msg); synchronized(socketList){ for(int i=0;i<socketList.size();i++){ Socket SendSocket = (Socket)this.socketList.get(i); OutputStream out = ((Socket)this.socketList.get(i)).getOutputStream(); // ((Socket)this.SocketList.get(i).getOutputStream(); PrintWriter pw = new PrintWriter(new OutputStreamWriter(out)); pw.println("[msg]:"+msg); pw.flush(); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.*; import java.util.*; public class Server { // Server를 추상화한 클래스 private int Port; private String ip; private ServerSocket serverSocket; private InetAddress addr; private ArrayList socketlist; // ArrayList말고 다른 방법 //1. 별도에 UserList //2. Thread public Server(int Port){ this.Port = Port; this.socketlist = new ArrayList(); } public void start(){ try { serverSocket = new ServerSocket(this.Port); while(true){ Socket clientsocket = serverSocket.accept(); synchronized(socketlist){ socketlist.add(clientsocket); } addr = clientsocket.getInetAddress(); System.out.println(addr.getHostAddress()+" 접속 인원"); //ClientThread ClientThread thread = new ClientThread(clientsocket,socketlist); thread.start(); /*for(int j=0;j<socketlist.size();j++){ // Socket client = (Socket)socketlist.get(j); if(client == clientsocket){ // 소켓비교 OutputStream out = client.getOutputStream(); PrintWriter pw = new PrintWriter(new OutputStreamWriter(out)); pw.println(addr.getHostName()+"님이 입장"); pw.flush(); } }*/ } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
1 2 3 4 5 6 7 8 9 10 11 | public class base { public static void main(String[] args) { Server server = new Server(10001); server.start(); } } |
결과
telnet을 이용해 여려개 접속이 가능하다.
반응형
'(Before)BitSchool' 카테고리의 다른 글
2014/05/27 JSP (0) | 2014.05.27 |
---|---|
2014/05/26 javanetwork - 직렬화, UDP (0) | 2014.05.26 |
2014/05/22 TCP/IP, 유틸리티API (0) | 2014.05.22 |
2014/05/21 javanetwork - 네트워크의 개요 (0) | 2014.05.21 |
2014/05/20 오라클 - PL/SQL, 프로시저, 함수생성 (1) | 2014.05.20 |