반응형
Gson을 이용한 json을 객체에 담기 
JsonObject -> 객체 변환

Gson 라이브러리는 json으로 받은 데이터를 내가 만든 객체에 자동으로 set 해주는 기능을 제공한다. 먼저 간단한 JsonObject 형태의 json을 객체로 변환해보자.

Member.java

package com.tistory.jekalmin;
public class Member {

    private String id;
    private String name;
    private int age;
    private String address;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "Member [id=" + id + ", name=" + name + ", age=" + age
                + ", address=" + address + "]";
    }



}

GsonTest.java

package com.tistory.jekalmin;

import com.google.gson.Gson;

public class GsonTest {

    public static void main(String[] args) {

        Gson gson = new Gson();
        String jsonString = "{'id':'jekalmin','name':'Min','age':26,'address':'Seoul'}";
        System.out.println(gson.fromJson(jsonString, Member.class));

    }
}

결과는 다음과 같다.

Member [id=jekalmin, name=Min, age=26, address=Seoul]



JsonArray -> List 변환

이번엔 조금더 까다로운 JsonList를 List로 변환해보자. Member.java 클래스는 동일하다.

GsonTest.java

package com.tistory.jekalmin;

import java.util.Arrays;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GsonTest {

    public static void main(String[] args) {

        Gson gson = new Gson();
        String jsonString = "[{'id':'jekalmin','name':'Min','age':26,'address':'Seoul'},{'id':'park','name':'park','age':27,'address':'Seoul'},{'id':'kim','name':'kim','age':28,'address':'Incheon'}]";

        // 방법1
        Member[] array = gson.fromJson(jsonString, Member[].class);
        List<Member> list = Arrays.asList(array);

        // 방법2
        List<Member> list2 = gson.fromJson(jsonString, new TypeToken<List<Member>>(){}.getType());

        System.out.println(list);
        System.out.println(list2);

    }
}

두 방법의 결과는 같은 것을 알 수 있다.

[Member [id=jekalmin, name=Min, age=26, address=Seoul], Member [id=park, name=park, age=27, address=Seoul], Member [id=kim, name=kim, age=28, address=Incheon]]
[Member [id=jekalmin, name=Min, age=26, address=Seoul], Member [id=park, name=park, age=27, address=Seoul], Member [id=kim, name=kim, age=28, address=Incheon]]

방법은 두가지 중에 아무거나 사용해도 될 것 같다.

 

반응형
LIST
반응형

* Gson JsonArray To List<String>

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;
// ...
Type listType = new TypeToken<List<String>>() {}.getType();
List<String> yourList = new Gson().fromJson(mapping.get("servers"), listType);

 

반응형
LIST
반응형

URLConnection vs HTTPURLConnection



URLConnection 객체를 쓸려거든, HTTPURLConnection으로 클래스타입 변환을 하고명시적으로disconnect() 메소드를 날려주는 것이 좋습니다.

HttpURLConnection conn = (HttpURLConnection)(newURL("http://www.google.com").openConnection());

conn.disconnect();


 

 

http 프로토콜을 가지는 URL 객체를 이용하여 openConnection() 메소드를 얻는 객체는 rt.jar에 있는sun.net.www.protocol.http.HttpURLConnection 객체를 얻어옵니다

사실 이 객체는 URLConnection  또는 HttpURLConnection 추상화 객체로 쓸 수 있습니다다만 큰 차이는 disconnect() 메소드를 호출할 수 있느냐 없는냐 수준입니다.

소스를 보면,  연결 후, 바로 끊도록 되어 있지만, keep alive때에 대해서 확인하는 절차가 있습니다.

 

 

URLConnection을 통해서 InputStream을 통해서 response를 다 읽어오면,  자연스럽게 접속이 끊기게 됩니다아시다시피 아파치 http 설정에 KeepAlive  Off로 되어 있으면 그렇습니다.

만약 KeepAlive On으로 되어 있으면연결이 끊기지 않도록 되어 있지요.

 

결국은 아파치 설정이 KeepAlive On 설정으로 셋팅되어 있을 수 있기 때문에 HttpURLConnection객체를 써서 disconnect()를 써야 하는 상황이라고 생각하시면 좋을 듯 싶습니다.

 

아파치 설정에 KeepAlive Off로 되어 있으면그 서버와 통신하는 클라이언트의 URLConnection을 사용해도 아무런 문제가 없습니다.  한게임 웹은 무조건 그런 설정을 따라가도록 되어 있습니다.

 

첨부파일에 보시면제가 수십 번의 테스트를 통해서 나름 결론을 내린 두개의 tcpdump 분석 데이터가 있습니다.

아파치 웹 서버가 KeepAlive  Off로 되어 있으면클라이언트에서 FIN을 보내서 종료하게 되고, KeepAlive On이면 대기하게 됩니다.  웹 서버가 KeepAlive On 상태인대계속 요청이 들어오게 되면연결이 많아져 점점 처리를 못하게 되어 ACK 통신이 어려워져 timeout 되어 FIN_WAIT로 이동할 것입니다. (아마도 거의 장애 상태에 부딪히게 됩니다이 상황은 보고된 장애 또는 도스 공격 상황와 매우 흡사한 상황입니다.)


출처: http://knight76.tistory.com/entry/URLConnection-vs-HTTPURLConnection

반응형
LIST
반응형

자바 :: JAVA :: Thread :: 쓰레드 :: 다중 상속

 
쓰레드(Thread)
한개의 프로그램 (한개의 프로세스)에서 여러개의 동시(시분할)작업을 시키고 싶을때.
하나의 프로세스 안에서 여러개의 병렬 Thread가 동시에 진행될수 있다.

여러개의 프로세스를 동시작업을 하면 속도, 리소스의 비용이 많이 들기 때문에
한개의 프로세스안에서 여러 쓰레드(작업단위)를 두어,
  가벼운 프로세스를 여러개 돌리는 효과

즉 작업의 단위가 여러개 라는건 반복문을 멀티로 돌릴 수 있다.
    1. 시계를 만들어 돌리고
    2. 키보드의 입력을 받으며 출력
    3. 이미지가 계속 바뀌면서 동적으로 움직인다.


1)하나의 프로그램은 하나의 프로세스로 동작.
   하나의 프로세스는 최소 한개의 쓰레드로 동작(주 쓰레드)
   main()메소드가 시작하면 main쓰레드가 동작
2)주 쓰레드는 별도의쓰레드를 생성하지 않고 System.exit(0)를 호출하지 않는다면,
   main()메소드가 종료될때 주 쓰레드는 종료 된다.
   주 쓰레드가 종료되면 프로세스안에 쓰레드가 하나도 없기 때문에
   프로세스는 종료-->프로그램 종료
3)만일 도중에 별도의 쓰레드를 만든다면 이 프로세스는 동시에 실행되는
   복수개의 쓰레드를 가짐  이렇게 나중에 만들어진 쓰레드는 main()메소드가
   시작점이 아니고 run()메소드가 시작점이자 종료점이다.
4)복수의 쓰레드를 가진 프로세스는 주 쓰레드(main 쓰레드)를 포함한
   모든 쓰레드가 종료해야 비로서 종료한다.
   일반적으로 한 프로세스내의 생성된 모든 쓰레드가 종료되야 프로세스가 종료됨.

쓰레드가 하나일경우
│프로세스시작 ─────────────────  끝│
│main 쓰레드 시작 ─────────────── 끝│
   (main()함수 시작)                            (main()함수 끝)


쓰레드가 여러개일 경우
│프로세스시작 ───────────────────────────────  끝│
│main 쓰레드 시작 ───────────────── 끝│
           | Thread1시작 ───────────────────── 끝│
               (run()함수시작                                              (run()함수 끝)
               | Thread1시작 ──────────────────────────  끝│


쓰레드 만들기(어떻게 Thread를 만드는가?)
1.Thread class를 상속받아 사용하면 우리 class는 Thread로 동작
  (Thread - 병렬, 동시에, 멀티로)

2.run()함수를 call하면 실제 이때 새로운 Thread가 탄생

   main쓰레드는 main()함수가 진입지점
   그외 사용자 정의 쓰레드는 run()함수가 진입지점

쓰레드의 사용
  • 구현하고자하는 클래스가 Thread 클래스를 상속 받게한다.
  • run()메소드를 오버라이딩해서 쓰레드로 작동해야 하는 코드 삽입.
  • 클래스의 객체 생성
  • Start()메소드를 호출한뒤 쓰레드 실행

아래의 예제로 기본적인 Thread사용법을 알아보겠습니다.
 Given : Thread1.java
 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.*;
public class Thread1 extends Thread{
    //extends Thread는 다중작업을 시작하겠다는 선언이다.
    
    public static void main(String[] args){    //main쓰레드 생성 지점.
        System.out.println("쓰레드를 확인해보자.");
        //현재 돌고있는 쓰레드를 객체로 반환.
        Thread ct =Thread.currentThread();
        String name = ct.getName();
        System.out.println("현재 쓰레드 이름 : " + name);
       
        ct.setName("my");
        System.out.println(ct.getName());
       
        //현재 몇개의 쓰레드가 돌고 있나?
        System.out.println("쓰레드 갯수 : " + Thread.activeCount());
       
        //쓰레드 여러개 동작하게하기
        Scanner sc = new Scanner(System.in);
        String line =null;
       
        Thread1 t1= new Thread1();
        t1.start(); //run()메소드를 호출하려면 start()메소드를 호출함.
       
        while(true){    //main쓰레드가 1가지 작업밖에 하지 못한다..
            System.out.print("문자를 입력하세요 : ");
            line = sc.next(); //사용자가 문자열 치고 엔터치기 기다린다.
            System.out.println("입력하신 문자열은 : " + line + "입니다.");
            System.out.println(line);
           
            if(line.equals("quit")){
                break;
            }
        }
    }//main 쓰레드 종료지점.
    public void run(){        //새로운 쓰레드의 진입지점.
        System.out.println("새로운 쓰레드가 생성됩니다.");
        for(int i = 1 ; i<100; i++){
            System.out.println(Thread.currentThread().getName()+ " : "+ i);
            System.out.println("현재 쓰래드 갯수 : " + Thread.activeCount());
           
            try{ sleep(1000);
            }catch(Exception e){}
        }
    }//새로운 쓰레드의 종료지점
}

참조]위 예제는 for문으로 1~100까지 "현재쓰래드 갯수 i"를 출력하게 하고
        사용자로부터 키보드 값을 받아 출력하는.. 두가지일을 하는 예제입니다.


 Given : Thread2.java
 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
34
35
36
37
38
39
40
41
42
43
44
45
public class Thread2 extends Thread{
    public static void main(String[] args){
        System.out.println("::::::::main쓰레드 시작::::::::");
       
        MyThread1 mt1 =new MyThread1();
        MyThread2 mt2 =new MyThread2();
        mt1.start();
        mt2.start();
       
        for(int i=0; i<5; i++){
            System.out.println();
            System.out.println("main Thread : "+ i);
            System.out.println();
            try{
                Thread.sleep(3000);
            }catch(Exception e){}
        }
       
        System.out.println("::::::::main쓰레드 종료::::::::");
    }
}

class MyThread1 extends Thread{
    public void run(){
        for(int i=1; i<7; i++){
            System.out.println("MyThread1 : " + i);
            try{
                sleep(1000);    //1초마다 한번씩 cpu처리를 받음.
            }catch(Exception e){}
        }
        System.out.println("MyThread1 종료");
    }
}
class MyThread2 extends Thread{
    public void run(){
        for(int i=1; i<5; i++){
            System.out.println("MyThread2 : " + i);
            try{
                sleep(2000);
            }catch(Exception e){}
        }
        System.out.println("MyThread2 종료");
    }
}

참조]위 예제는 main 쓰레드와 'MyThread1', 'MyThread2' 쓰레드를 이용하여 시간차를
       주고 메시지를 출력하는 예제입니다.




Thread-Runnable 인터페이스
     
자바는 다중 상속을 지원하지 않기 때문에 새로운 클래스가 다른 클래스를
 상속 받는다면 Thread 클래스를 상속하여 사용할 수 없다.
이때 Runnable 인터페이스를 구현하여 쓰레드를 사용하게 된다.
참고 ──────────────────
class A{
   aaa(){A}
}
class B{
   aaa(){B}
}
class extends A,B{}  
──────────────────────
위 코드처럼 다중상속은 불가능하다. 하지만..
아래의 코드 처럼 멀티 implements는 가능하다.
──────────────────────
interface A{
  aaa(){A}
}
interface B{
  aaa(){B}
}
class implements A,B{}         
──────────────────────


Runnable
  • run()메소드를 오버라이딩 하여 사용
  •  public void run(){} ┃

  • 클래스의 객체 생성
  • 생성한 객체를 인자로 Thread객체를 생성
  • 쓰레드 객체의 start()메소드를 호출하여 쓰레드 실행


Thread-Runnable를 이용한 예제를 살펴보자.
  Given : Thread3.java
 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
import javax.swing.*;
public class Thread3 extends JFrame implements Runnable{
    public static void main(String[] args){
        System.out.println(":::::::::main Thread Start:::::::::");
        Thread3 t3 = new Thread3();
        //[1]Runnable 구현한 클래스를 객체화
       
        Thread t = new Thread(t3);
        //[2]Thread 클래스로 새로운 쓰레드를 만드는데
        //생성자의 인자로 Runnable인터페이스를 구현한 객체를 넣음
       
        t.start();
        //[3]start()메소드를 호출.
       
        for(int i=0; i<10; i++){
            System.out.println("MyThread : "+ i);
           
            try{Thread.sleep(1000);
            }catch(Exception e){}
           
        }
       
        System.out.println(":::::::::main Thread End:::::::::");
    }
    public void run(){
    //    이 thread가 별개의 Runnable 실행 객체를 사용해 작성되었을 경우,
    //    그 Runnable 객체의 run 메서드가 호출됩니다. 그렇지 않은 경우,
    //    이 메서드는 아무것도 실시하지 않고 복귀합니다.
    //    Thread 서브 클래스는 이 메서드를 오버라이드(override)
    //    하지 않으면 안됩니다.
    }
}

 
이미지 참조 : http://blog.naver.com/xyzeon

준비 : 실행상태로 들어가기 위해 준비하고 있는 상태로
           start()메서드가 호출된 쓰레드는 기본적으로 준비상태
실행: 쓰레드 스케줄러에 의해 선택되면 실행 상태로 들어가게 되며
          이때 run()메서드의 코드가 실행
종료: run()메서드가 종료되어 쓰레드의 실행이 완료된 상태로 한번 종료된
         쓰레드는 다시 실행상태가 될 수 없다. 실행상태가 될 수는 없지만
          객체가 사라지는 것은 아니므로 객체의 메서드나 멤버변수의 호출은 가능
실행정지: 실행이 정지된 상태는 대기,슬립,지연3가지 형태로 구분.
               실행정지 상태는 준비상태와는 다르게 특정 메서드의 호출이나
               이벤트가 발생될 때까지 실행되지 못함.
      •-대기: 동기화 블록 내에서 쓰레드 실행중지, notify()에 의해 깨워지기를 기다리는 상태
      •-슬립: CPU의 점유를 중지, 특정시간동안 대기
      •-지연: 입출력 메서드 등의 호출로 인해 해당 메서드의 종료가 일어날 때까지 대기하고 있는 상태
Thread-상태 참조 : http://blog.naver.com/xyzeon
반응형
LIST

+ Recent posts