본문 바로가기

(Before)BitSchool

2014/05/23 java network - 쓰레드, Thread

반응형

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 인터페이스를 사용하면 상속도 가능하게 된다는 장점이 있다.

 Colored By Color Scripter

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을 이용해 여려개 접속이 가능하다.






반응형