본문 바로가기

   
Programming/Java

19일차!

반응형
Thread
멀티유저, 멀티태스크 동시에 여러 프로그램이 실행
각각의 프로세스 실행 -> 각각의 프로세스가 독립적 그러므로 각각의 프로세스와 정보 공유가 힘들다.
cpu나 메모리에 전용 영역이 할당 해당 프로그램이 사용할수 있는것.
program process안에서 실행되는 작업
한개의 자원을 가지고 두개의 스레드가 자원 공유 가능

서블릿 jsp -> web application(웹서버에 배포작업을 거침)
main.jsp에 사람들이 모두 몰린다면 -> 동시작업이 필요 각각의 쓰레드로 main.jsp를 실행

package thread;

public class MyThread extends Thread {
      //스레드를 만드는 방법 1. Thread를 상속받는다. run() 메소드를 재정의     2. Rounnable를 구현한다. run()메소드를 구현  
      //스레드의 run() 메소드 - 동시에 실행시키고 싶은 작업을 구현한다. 스레드의 start() 메소드 - 스레드를 싱행가능한 상태로 만든다. - JVM의 스케줄러가 스레드를 실행시킨다.
      @Override
      public void run() {
           String threadName = this.getName();
            for( int i=0; i<100; i++){
                System. out.println( "["+ threadName+ "]" + i);
           }
     }
      public static void main(String[] args) {
            //동시에 실행시키고 싶은 작업이 궇련된 스레드를 여러 개 만든다.
            MyThread t1 = new MyThread ();
            MyThread t2 = new MyThread ();
            MyThread t3 = new MyThread ();
           
            //스레드를 실행가능상태로 바꾼다.
            t1.start();
            t2.start();
            t3.start();
            /**결과화면_______
            *  [Thread -0]0
                [Thread -0]1
                [Thread -0]2
                [Thread -0]3
                [Thread -0]4
                [Thread -2]0
                [Thread -1]0
                [Thread -2]1
                [Thread -0]5
                [Thread -2]2
                [Thread -1]1
                [Thread -2]3
            */
     }
}


package thread;

import java.util.Random;

import javax.swing.JProgressBar;

public class RaceThread extends Thread {
     
     JProgressBar bar;
     
      public RaceThread(JProgressBar bar){
            this. bar = bar;
     }
     
      @Override
      public void run() {
            try{
                Random random = new Random();
                 for( int i=0; i<=100; i++){
                      bar.setValue( i);
                     Thread. sleep( random.nextInt(500)); //프로그램을 잠깐 잠자게함 슬립시간
                }
           } catch(Exception e){}
     }
     
}


package thread;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JButton;

public class Race {

      private JFrame frame;

      /**
      * Launch the application.
      */
      public static void main(String[] args) {
           EventQueue. invokeLater( new Runnable() {
                 public void run() {
                      try {
                           Race window = new Race();
                            window. frame.setVisible( true);
                     } catch (Exception e) {
                            e.printStackTrace();
                     }
                }
           });
     }

      /**
      * Create the application.
      */
      public Race() {
           initialize();
     }

      /**
      * Initialize the contents of the frame.
      */
      private void initialize() {
            frame = new JFrame();
            frame.setBounds(100, 100, 603, 234);
            frame.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE );
            frame.getContentPane().setLayout( null);
           
           JProgressBar Bar1 = new JProgressBar();
            Bar1.setBounds(12, 10, 563, 32);
            frame.getContentPane().add( Bar1);
           
           JProgressBar Bar2 = new JProgressBar();
            Bar2.setBounds(12, 63, 563, 32);
            frame.getContentPane().add( Bar2);
           
           JProgressBar Bar3 = new JProgressBar();
            Bar3.setBounds(12, 121, 563, 32);
            frame.getContentPane().add( Bar3);
           
            Bar1.setStringPainted( true);
            Bar2.setStringPainted( true);
            Bar3.setStringPainted( true);
           
            Bar1.setValue(50);
            Bar2.setValue(30);
            Bar3.setValue(70);
           
           JButton btn = new JButton( "\uC2A4\uD0C0\uD2B8" );
            btn.setBounds(237, 163, 97, 23);
            frame.getContentPane().add( btn);
            btn.addActionListener( e->{
                 //3개의 동시작업
                RaceThread t1 = new RaceThread( Bar1);
                RaceThread t2 = new RaceThread( Bar2);
                RaceThread t3 = new RaceThread( Bar3);
                
                 t1.start();
                 t2.start();
                 t3.start();
                
           });
     }
}




동기화
동기화처리가 되어있다.
     - Vector, StringBuffer
     - Thread safe하다.
동기화처리가 되어있지 않다.
     - ArrayList, StringBuilder
     - Thread unsafe하다.
모든객체에는 LOCK의 기능이 있다. 보통때는 사용되지 않으나 동기화 처리를 하게되면 LOCK의 기능이 발동된다.
여러객체중 키를 얻어낸 객체만 데이타를 얻을수 있다.

package thread;

public class ATMDemo {
      public static void main(String[] args) {
           ATM atm = new ATM();
           
            //Thread를 만들떄 위에서 생성한 객체를 넣어서 만든다.
           Thread t1 = new Thread( atm, "길동" );
           Thread t2 = new Thread( atm, "순신" );
           Thread t3 = new Thread( atm, "감찬" );
           
            t1.start();
            t2.start();
            t3.start();
/**결과화면_________________
 *  [길동]이 잔액을 확인중입니다..
     [길동]이 비번을 확인중입니다.
     [길동]이 인출중입니다.
     [길동]이 잔액을 확인중입니다..
     [길동]이 비번을 확인중입니다.
     [길동]이 인출중입니다.
     [길동]이 잔액을 확인중입니다..
     [길동]이 비번을 확인중입니다.
     [길동]이 인출중입니다.
     [감찬]이 잔액을 확인중입니다..
     [감찬]이 비번을 확인중입니다.
     [감찬]이 인출중입니다.
     [감찬]이 잔액을 확인중입니다..
     [감찬]이 비번을 확인중입니다.
     [감찬]이 인출중입니다.
     [감찬]이 잔액을 확인중입니다..
     [감찬]이 비번을 확인중입니다.
     [감찬]이 인출중입니다.
     [순신]이 잔액을 확인중입니다..
     [순신]이 비번을 확인중입니다.
     [순신]이 인출중입니다.
     [순신]이 잔액을 확인중입니다..
     [순신]이 비번을 확인중입니다.
     [순신]이 인출중입니다.
     [순신]이 잔액을 확인중입니다..
     [순신]이 비번을 확인중입니다.
     [순신]이 인출중입니다.
     길동잔액을 확인:1000000000
     길동인출금액을 확인:200000000
     길동200000000
     길동인출 후  잔액은 800000000입니다.
     길동처리완료
     길동잔액을 확인:800000000
     길동인출금액을 확인:200000000
     길동200000000
     길동인출 후  잔액은 600000000입니다.
     길동처리완료
     길동잔액을 확인:600000000
     길동인출금액을 확인:200000000
     길동200000000
     길동인출 후  잔액은 400000000입니다.
     길동처리완료
     길동잔액을 확인:400000000
     길동인출금액을 확인:200000000
     길동200000000
     길동인출 후  잔액은 200000000입니다.
     길동처리완료
     길동잔액을 확인:200000000
     길동인출금액을 확인:200000000
     길동200000000
     길동인출 후  잔액은 0입니다.
     길동처리완료
     감찬잔액을 확인:0
     감찬인출금액을 확인:200000000
     감찬처리완료
     감찬잔액을 확인:0
     감찬인출금액을 확인:200000000
     감찬처리완료
     감찬잔액을 확인:0
     감찬인출금액을 확인:200000000
     감찬처리완료
     감찬잔액을 확인:0
     감찬인출금액을 확인:200000000
     감찬처리완료
     감찬잔액을 확인:0
     감찬인출금액을 확인:200000000
     감찬처리완료
     순신잔액을 확인:0
     순신인출금액을 확인:200000000
     순신처리완료
     순신잔액을 확인:0
     순신인출금액을 확인:200000000
     순신처리완료
     순신잔액을 확인:0
     순신인출금액을 확인:200000000
     순신처리완료
     순신잔액을 확인:0
     순신인출금액을 확인:200000000
     순신처리완료
     순신잔액을 확인:0
     순신인출금액을 확인:200000000
     순신처리완료
           
 */
     }
}


package thread;

public class ATM implements Runnable {
     
      private long balance = 1000000000;
     
      public void run() {
            for( int i=0; i<5; i++){
                withdraw();     
           }
     }
     
      //synchronized 안전하지만 속도가 느려지는 단점이 있다.
      //교착상태가 일어날 확률이 많아지고 자원관리가 쉽지 않다.
      //멀티쓰레드 환경에서는 가격이 변하는 변수를 연산하려면 해당 메소드에 싱크로나이즈(동기화) 처리를 해주어야 한다.
      //lock상태에서 메소드를 빠져나오려면 키가 필요하다.
      public synchronized void withdraw(){
           String name = Thread. currentThread().getName();
           System. out.println( name + "잔액을 확인:" + balance );
           System. out.println( name + "인출금액을 확인:" + 200000000);
            if( balance >= 200000000){
                System. out.println( name + "200000000");
                 balance -= 200000000;
                System. out.println( name + "인출 후  잔액은 " + balance + "입니다." );
           }
           System. out.println( name + "처리완료" );
//         for( int i=0; i<3; i++){
//              String name = Thread.currentThread().getName();
//              System.out.println("["+name+"]이 잔액을 확인중입니다..");
//              System.out.println("["+name+"]이 비번을 확인중입니다.");
//              System.out.println("["+name+"]이 인출중입니다.");
//         }
     }
}



네트워크

CS 모델
클라이언트 / 서버
예전에는 통신기능도 개발자가 코딩했어야했다. 쓰레드도 잘했어야 했고 네트웍도 잘했어야 햇었다.
이때 웹이 나타남 

클라이언트(브라우져)
웹어플리케이션 서버 WAS(서버) - JBOSS, WEBROGIC, ZEUS
서버에서 돌리고싶은 업무로직이 DB추출 등... 서버에서 구동될 프로그램
네트웍 스레드를 몰라도 클라이이언트와 서버가 알아서 처리해줌.
package network;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class AddressDemo {
      public static void main(String[] args) throws Exception {
            //host명에 해당하는 ip 주소 정보 얻기
           InetAddress a = InetAddress.getByName( "www.daum.net");
            /*
            * InetAddress를 객체를 얻으면
            * ip주소정보를 얻을 수 있다(이사실이 중요)
            */
           String address = a.getHostAddress();
           System. out.println( address);
           
            //로컬 컴퓨터(내컴퓨터)의 ip주소정보얻기
           InetAddress b = InetAddress. getLocalHost();
           System. out.println( "컴퓨터 이름:" + b .getHostName());
           System. out.println( "ip주소:" + b .getHostAddress());
           
            /**
            * http:// www.daum.net    80     /society/others/news.jsp   ? newsid=201504301921&cat=policy
            */ //프로토콜         호스트명     
            //포트번호               경로                                    쿼리 스트링
            /**결과화면___________
            * 180.70.134.91
                컴퓨터 이름:L3 -20
              ip주소:192.168.0.5
            */
           

     }
}


소켓
클라이언트 - 클라이언트 소켓 이라는 객체 생성(서버의 IP를 지정, 서버의 포트번호 지정) IP에 해당하는 서버에 접속해서 연결요청을함.
서버 - 연결요청을 기다리고 있는놈을 서버 소켓
package net;

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

public class ServerDemo {
      public static void main(String[] argsthrows Exception{
            //포트번호 8888번에서 실행중인 서버 만들기 //Server -> 서비스 제공, 컨텐츠 제공
            //지정된 port로 들어오는 client의 연결을 기다린다.
            //clinet의 연결요청이 오면 그 client와 통신을 담당하는 socket을 생성한다.
           ServerSocket server = new ServerSocket(8888);
           System. out.println( "서버가 시작되었습니다. 연결을 기다리는 중..");
           
           Socket socket = server.accept();
           String ipaddress = socket.getInetAddress().getHostAddress();

           System. out.println( ipaddress + "에서 접속하였습니다." );
     }
}
//서버 <메세지 교환 형식을 정의 = 프로토콜> 클라이언트
//binnary data(2진수 변환), text data(plain text, jsonxml)
//0~1024포트번호는 예약되어 있기 떄문에 사용할수 없음.


package net;

import java.io.OutputStream;
import java.net.Socket;

public class ClientDemo {
      public static void main(String[] argsthrows Exception {
            //서비스요청, 실 사용자가 사용하는 program
            //socket 컴퓨터 2대(서버, 클라이언트)가 서로 통신하기 위해서 필요한것
            //두컴퓨터간의 연결을 유지하고, 데이터 교환을 책임진다.
            //socket쪽으로 데이타를 흘려보내면 연결된 반대편 소켓으로 보내진다.
           Socket socket = new Socket( "192.168.0.9", 8888);
           OutputStream os =  socket.getOutputStream();
            os.write( "그라라라라라라~~" .getBytes());
     }
}


반응형