읽어보고 article 새로 쓰기: http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html

출처: http://stackoverflow.com/questions/2927391/whats-the-reason-i-cant-create-generic-array-types-in-java

Arrays of generic types are not allowed because they're not sound. The problem is due to the interaction of Java arrays, which are not statically sound but are dynamically checked, with generics, which are statically sound and not dynamically checked. Here is how you could exploit the loophole:


출처: http://download.oracle.com/javase/tutorial/java/generics/erasure.html

Type Erasure

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

For instance, Box<String> is translated to type Box, which is called the raw type — a raw type is a generic class or interface name without any type arguments. This means that you can't find out what type of Object a generic class is using at runtime. The following operations are not possible:

public class MyClass<E> {
    public static void myMethod(Object item) {
        if (item instanceof E) {  //Compiler error
            ...
        }
        E item2 = new E();       //Compiler error
        E[] iArray = new E[10];  //Compiler error
        E obj = (E)new Object(); //Unchecked cast warning
    }
}

The operations shown in bold are meaningless at runtime because the compiler removes all information about the actual type argument (represented by the type parameter E) at compile time.

Type erasure exists so that new code may continue to interface with legacy code. Using a raw type for any other reason is considered bad programming practice and should be avoided whenever possible.

When mixing legacy code with generic code, you may encounter warning messages similar to the following:

Note: WarningDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

This can happen when using an older API that operates on raw types, as shown in the following WarningDemo program:

public class WarningDemo {
    public static void main(String[] args){
        Box<Integer> bi;
        bi = createBox();
    }

    static Box createBox(){
        return new Box();
    }
}

Recompiling with -Xlint:unchecked reveals the following additional information:

WarningDemo.java:4: warning: [unchecked] unchecked conversion
found   : Box
required: Box<java.lang.Integer>
        bi = createBox();
                      ^ 
1 warning 

'Archive' 카테고리의 다른 글

Java에서 현재 스택 상황을 보는 방법  (0) 2011.11.16
Java에서 메소드명(String)으로 메소드 호출하기  (0) 2011.11.16
In Praise Of Small Code  (0) 2011.11.15
Hollywood Principle  (0) 2011.11.15
A Taxonomy for "Bad Code Smells"  (0) 2011.11.15
  
출처: http://stackoverflow.com/questions/2223386/why-doesnt-java-allow-overriding-of-static-methods

Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.


  

출처: http://tech-read.com/2008/06/19/why-inner-class-can-access-only-final-variable/

Local classes can most definitely reference instance variables. The reason they cannot reference non final local variables is because the local class instance can remain in memory after the method returns. When the method returns the local variables go out of scope, so a copy of them is needed. If the variables weren’t final then the copy of the variable in the method could change, while the copy in the local class didn’t, so they’d be out of synch.

Anonymous inner classes require final variables because of the way they are implemented in Java. An anonymous inner class (AIC) uses local variables by creating a private instance field which holds a copy of the value of the local variable. The inner class isn’t actually using the local variable, but a copy. It should be fairly obvious at this point that a “Bad Thing”™ can happen if either the original value or the copied value changes; there will be some unexpected data synchronization problems. In order to prevent this kind of problem, Java requires you to mark local variables that will be used by the AIC as final (i.e., unchangeable). This guarantees that the inner class’ copies of local variables will always match the actual values.

  

Exception에 관하여

Posted by epicdev Archive : 2011. 10. 8. 17:23
출처: http://babtingdev.tistory.com/302

 try { 
   ...
} catch (SQLException e) {} 

보통 예외를 잡고는 아무것도 하지 않는 이러한 코드를 많이 작성한다. 예외 발생을 무시해 버리고 정상적인 상황인 것처럼 다음 라인으로 넘기겠다는 분명한 의도가 있는게 아니라면 연습 중에도 절대 만들어서는 안되는 코드이다.
이것은 예외가 발생하는 것보다도 훨씬 안좋은 상황을 만든다. 오류가 있는 건데 오류를 무시하고 계속 진행해버리기 때문이다.

try {
   ...
} catch(SQLException e) {
   System.out.println(e);
}

try {
   ...
} catch(SQLException e) {
   e.printStackTrace();
}

위 두개도 마찬가지로 사용해선 안될 코드들 이다. 예외는 처리되어야 한다.

예외를 처리할 때 반드시 지켜야 할 원칙은 한가지 이다. 모든 예외는 적절하게 복구되던지 아니면 작업을 중단시키고 운영자 또는 개발자에게 분명하게 통보되야 한다.

무의미하고 무책임하게 throws를 사용하는 개발자들도 있다. 처리하기 귀찮으니 그냥 메소드 선언부에 throws 를 써서 넘겨버리는 것이다. (아래 코드와 같이.)
public void method1() throws Exception {
}
try~catch로 Exception을 삼켜버리는 코드보다야 낫지만 무작정 throws 를 남발하는 이 방법도 매우 안좋은 방법이다. 


예외의 종류와 특징에 대해 알아보자.
1. Error 
java.lang.Error 클래스의 서브클래스들이다. 에러는 시스템에 뭔가 비정상적인 상황이 발생했을 경우에 사용된다. 그래서 주로 자바VM에서 발생시키는 것이고 어플리케이션 코드에서 잡으려고 하면 안된다. OutOfMemoryError나 ThreadDeath같은 에러는 catch블록으로 잡아봤자 대응 방법이 없기 떄문이다.

2. Exception
java.lang.Exception 클래스와 그 서브클래스로 정의되는 예외들은 개발자들이 만든 어플리케이션 코드의 작업중에 예외상황이 발생했을 경우에 사용된다.
Exception은 체크예외와 언체크 예외로 구분된다. 언체크 예외는 Exception의 서브클래스이며 RuntimeException클래스를 상속받은 클래스이며 체크 예외는 RuntimeException클래스를 상속받지 않은 나머지 Exception의 서브클래스들이다.

2.1 체크예외
체크예외는 무조건 처리되어야 하는 예외이다. try~catch, throws를 통해 어떻게든 처리를 하지 않으면 컴파일 에러가 난다.
IOException이나 SQLException이 대표적이다.

2.2 언체크/런타임 예외
java.lang.RuntimeException 클래스를 상속한 예외들이며 명시적인 예외처리를 강제하지 않는다. (try~catch, throws등의 처리를 안해도 컴파일 에러가 안난다는 의미.)
물론 명시적인 처리를 하는 것도 가능하다. 
런타임 예외는 주로 프로그램의 오류가 있을 때 발생하도록 의도된 것이다. NullPointerException이나 IllegalArgumentException등이 대표적이다. 피할 수 있지만 개발자가 부주의 해서 발생할 수 있는 경우에 발생하도록 만든 것이 런타임 예외이다. 따라서 런타임 예외는 예상하지 못했던 예외상황에서 발생하는게 아니기 떄문에 명시적인 처리를 하지 않아도 되게 만든 것이다.


이제 예외를 처리하는 방법에 대해 알아보자.

1. 예외복구
예외상황을 파악하고 문제를 해결해서 정상상태로 돌려놓는 것이다. 예를 들면 읽으려는 파일이 없을때 IOException이 발생할 것이다. 이 예외가 발생한 상황을 다른 파일을 읽도록 안내하는 걸로 해서 예외상황을 해결할 수 있다.

2. 예외처리 회피
예외처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 것이다. 
public void add() throws SQLException {
}

public void add() throws SQLException {
   try {
      ...
   } catch(SQLException e) {
      throw e;
   }
}
하지만 이 방법은 무책임한 책임회피가 될 수 있다. 예를 들어 DAO가 SQLException을 생각없이 던졌다면?
DAO를 사용하는 서비스 계층이나 웹 컨트롤러에게 이 SQLException이 전달 될 것이다. 과연 서비스 계층이나 웹 컨트롤러 계층에서 이 SQLException을 처리하는게 맞는 것인가? 처리는 할 수 있나? 아마 이 예외는 그냥 처리되지 않고 서버로 던져지게 될 것이다.
예외를 회피하는 것은 예외를 복구하는 것처럼 의도가 분명해야 한다. 예외를 회피하는 것은 자신을 호출해서 사용하는 쪽에서 이 예외를 다루는게 최선의 방법이라는 확신이 있을 경우에만 사용하도록 한다.

3. 예외 전환
예외 회피와 비슷하게 예외를 복구해서 정상적인 상태로 만들 수 없는 경우 예외를 메소드 밖으로 던진다. 하지만 예외회피와는 달리 발생한 예외를 그냥 던지는 것이 아니라 적절한 예외로 전환해서 던진다.
첫째는 내부에서 발생한 예외를 그대로 던지는 것이 그 예외 상황에 대한 적절한 의미를 부여해주지 못하는 경우, 의미를 분명하게 해줄 수 있는 예외로 바꿔주기 위해서이다.
예를 들면 사용자를 DB에 insert하다가 동일한 id가 있어 에러가 났다고 하자. JDBC API는 SQLException을 발생시킨다. 이 경우 DAO가 그냥 SQLException을 던지면 이를 이용하는 서비스 계층에서는 무슨 의미인지 파악하기 힘들 것이다. 이런 경우 SQLException을 DuplicatUserIdException 같은 예외로 바꿔서 던져주는게 좋다.

catch(SQLException e) {
   if(e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY)
      throw DuplicateUserIdException();
   else 
      throw e;
}

보통 예외를 전환해서 던져줄때에는 원래 발생한 예외를 담아서 중첩예외로 만드는 것이 좋다.
중첩 예외로 만들었을 경우에는 getCause() 메소드를 이용해서 처음 발생한 예외가 무엇인지 확인할 수 있기 때문이다.
생성자나 initCause()메소드로 근본 원인이 되는 예외를 넣어주면 된다.

catch(SQLException e) {
    throw DuplicationUserIdException(e);
}

catch(SQLException e) {
    throw DuplicationUserIdException().initCause(e);
}

예외전환을 사용하는 경우는 위의 경우도 있지만 주로 예외처리를 강제하는 체크 예외를 예외처리를 강제하지 않는 런타임 예외로 바꾸는 경우에 사용한다.
DAO에서 발생한 SQLException이 웹 컨트롤러까지 전달이 된다고 해서 무슨 소용이 있을까? 웹 컨트롤러의 메소드에 throws SQLException이 선언되어 있다면 이를 어떻게 해석해야 할까? 어차피 복구가 불가능한 예외라면 가능한 빨리 런타임 예외로 포장해 던지게 해서 다른 계층의 메소드를 작성할 때 불필요한 throws 선언이 들어가지 않게 해야한다. DAO에서 발생한 SQLException이지 웹컨트롤러와는 사실 상관이 없는 예외이기 때문에 헷갈릴만한 상황을 만들면 안된다.
어차피 복구하지 못할 예외라면 어플리케이션 코드에선 런타임 예외로 포장해서 던지고, 예외처리 서비스 등을 이용해 자세한 로그를 남기고, 관리자에게 메일을 전송하고 사용자에겐 안내메시지를 보여주는 것도 처리 방법이다.


자바가 처음 만들어 질때는 AWT, Swing 등을 사용해서 독립형 어플리케이션을 개발했었다. 이때는 사용자가 입력한 이름에 해당하는 파일을 찾을 수 없다고 어플리케이션이 종료가 되면 안되었었다. 어떻게든 처리를 했어야 했다.
하지만 자바 엔터프라이즈 서버 환경은 다르다. 수많은 사용자가 요청을 보내고 각 요청들이 독립적인 작업으로 취급된다. 요청을 처리하다 예외가 발생하면 해당 작업만 중단시키면 된다. 독립형 어플리케이션과는 달리 서버의 특정 계층에서 예외가 발생했을 때 작업을 일시 중지하고 사용자와 바로 커뮤니케이션하면서 예외상황을 복구할 수 있는 방법은 없다.

최근에 등장하는 표준스펙 또는 오픈소스 프레임웍에서는 API가 발생시키는 예외를 체크예외 대신 언체크 예외로 정의하는 것이 일반화되고 있다. 예전에는 복구할 가능성이 조금이라도 있다면 체크예외로 만든다고 생각했는데 지금은 항상 복구할 수 있는 예외가 아니면 일단 언체크/런타임 예외로 만드는 경향이 있다.

체크예외를 언체크/런타임 예외로 만드는걸 구현해보자. 대표적인 체크예외가 SQLException이다. 그 중 동일한 pk를 
입력했을때 에러가 발생해서 SQLExcepion이 나는 상황을 구현해 보겠다.

일단  동일한 pk가 입력이 되었을 경우 사용할 RuntimeException을 상속받은 DuplicateKeyException 을 만들어 보자.
public class DuplicateKeyException extends RuntimeException {
   public DuplicateKeyException(Throwable cause) { // 중첩 예외를 만들기 위해 생성자를 만들어 이용.
      super(cause);
   }
}

이제 add() 메소드를 구현해 보겠다.
public void add() throws DuplicateKeyException {
    try {
         ...
    } catch(SQLException e) {
         if(e.getErrorCode() == MysqlErrorNumbers.ER_DUP_ENTRY) // Mysql 일 경우.
              throw new DuplicateKeyException(e); // 예외 포장
         else 
              throw new RuntimeException(e);
    }
}

RuntimeException을 사용하게 되면 꼭 예외 처리가 필요한 경우는 놓칠 수도 있게 된다. 반드시 예외를 catch해서 조치를 취하도록 요구하는 예외를 일반적으로 어플리케이션 예외라고 한다.
흔히 에러가 났을 경우 처리하는 작업이 특정 코드값을 정해서 리턴하는 방법이 있다. 
0이면 에러, 1이면 정상 이런 식으로...
이 방법은 각 코드값들을 명확하게 정리를 잘 해놓지 않으면 흐름을 파악하고 이해하기 어려워진다.
두번째 방법은 오류 발생시 비즈니스적인 의미를 띈 예외를 던지도록 하는 것이다. 물론 각 예외들은 위에 설명한 중첩방식같이 별도로 구현해서 사용을 해야 한다. 이 방법은 정상적인 흐름은 try {}안에 모아놓고 예외상황에 대한 코드들은 catch{}로 분리시킴으로 인해 깔끔하게 정리가 된다. 그리고 예외의 이름만 봐도 코드가 이해하기 편해지는 장점이 있다.
  

Java 필드 초기화

Posted by epicdev Archive : 2011. 10. 3. 15:27
출처: http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

Initializing Fields

As you have seen, you can often provide an initial value for a field in its declaration:
public class BedAndBreakfast {

    public static int capacity = 10;  //initialize to 10

    private boolean full = false;  //initialize to false
}
This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.

Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.


Static Initialization Blocks

static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example:
static {

    // whatever code is needed for initialization goes here
}
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.

There is an alternative to static blocks — you can write a private static method:

class Whatever {
    public static varType myVar = initializeClassVariable();
	
    private static varType initializeClassVariable() {

        //initialization code goes here
    }
}
The advantage of private static methods is that they can be reused later if you need to reinitialize the class variable.
 

Initializing Instance Members

Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods.

Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:

{

    // whatever code is needed for initialization goes here
}
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.

final method cannot be overridden in a subclass. This is discussed in the lesson on interfaces and inheritance. Here is an example of using a final method for initializing an instance variable:

class Whatever {
    private varType myVar = initializeInstanceVariable();
	
    protected final varType initializeInstanceVariable() {

        //initialization code goes here
    }
}
 
This is especially useful if subclasses might want to reuse the initialization method. The method is final because calling non-final methods during instance initialization can cause problems. Joshua Bloch describes this in more detail in Effective Java. 

출처: http://wahlstroem.org/bjorn/2008/07/24/instance-initializers-in-java/

At work I noticed an interesting piece of code. I wrote it in error, as I meant to write a static initializer (code that is run once when a static class is being referenced)


static {
// initialize static variables
}

but instead I wrote this


{
// initialize variables
}

It compiled nicely, but what is it good for?

The effect is not that of a static initializer, but it is actually run before the constructor; But not when referenced statically. You can have as many instance initializers as you want, and they are appearing to run in the order they are defined.

The author of “Java in a Nutshell” writes so nicely:

An instance initializer is simply a block of code inside curly braces that is embedded in a class definition, where a field or method definition normally appears.  A class (any class — not just anonymous classes) can have any number of instance initializers.  The instance initializers and any variable initializers that appear in field definitions for the class are executed in the order they appear in the Java source code.  These initializers are automatically run after the superclass constructor has returned but before the constructor, if any, of the current class runs.

This puzzles me, because this seems at first hand to be what we have constructors for. They are the blocks of code that is run whenever we instantiate a class, and should do all the complex logic and initialization that needs to be done to assure data integrity.

But; What about anonymous classes? You know, the ones that are used frequently in event-programming


someObject.addEventListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) { // .... }
});

They cannot have constructors, but I imagine it can be useful to have complex (more than one line..) initialization even there. Also, according to more seasoned programmers than my self, instance initializers can be used to make the code easier to read, since the initialization block can be placed right next to the variables.

The initializers are run in the order they are defined, and you can have as many you want. In contrast to constructors, which you can only have one of without an argument list. This could also be useful with regards to code readability, since complex constructors, like any block of code, should be avoided.

But beware, long-time maintenance could be troublesome if one isn’t careful. So-called “pretty”-tools often reorganize the code, e.g. alphabetically or by visibility. Since the instance initializers are run in the order they are defined, one has to make sure that they are not co-dependent. That would be a java-equivalent to Spaghetti Hell! 

'Archive' 카테고리의 다른 글

세부사항을 코드에서 몰아내라  (0) 2011.10.03
Camera의 setDisplayOrientation 메소드  (0) 2011.10.03
디미터 함수 법칙 (혹은 디미터 법칙)  (0) 2011.10.03
패키지의 순환적 의존성  (0) 2011.10.03
응답집합  (0) 2011.10.03
  

Object를 byte array로 쓰고 읽기

Posted by epicdev Archive : 2011. 9. 24. 00:01
출처: http://scr4tchp4d.blogspot.com/2008/07/object-to-byte-array-and-byte-array-to.html
 
privimive 타입이나 java.io.Serializable 인터페이스가 구현 된 객체만 쓰고 읽을 수 있음
public byte[] toByteArray (Object obj)
{
  byte[] bytes = null;
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  try {
    ObjectOutputStream oos = new ObjectOutputStream(bos); 
    oos.writeObject(obj);
    oos.flush(); 
    oos.close(); 
    bos.close();
    bytes = bos.toByteArray ();
  }
  catch (IOException ex) {
    //TODO: Handle the exception
  }
  return bytes;
}
    
public Object toObject (byte[] bytes)
{
  Object obj = null;
  try {
    ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
    ObjectInputStream ois = new ObjectInputStream (bis);
    obj = ois.readObject();
  }
  catch (IOException ex) {
    //TODO: Handle the exception
  }
  catch (ClassNotFoundException ex) {
    //TODO: Handle the exception
  }
  return obj;
}
  

블록킹 소켓 vs 논 블록킹 소켓

Posted by epicdev Archive : 2011. 9. 21. 15:19
출처: http://kin.naver.com/qna/detail.nhn?d1id=1&dirId=1040201&docId=125630325

- 블록킹 소켓에 대한 설명

블록킹 소켓을 사용하면 한 타임에 하나의 접속만 처리가 가능 합니다.

예를들어, 블록킹 소켓을 사용한 서버라고 가정하는 경우 서버의 역할상 동시다발적으로 복수의 클라이언트가 접속을 하여 서비스를 이용하게 되는데 블록킹 소켓을 사용하면 순차적으로 클라이언트의 접속을 받아들여 작업하고 해당 작업이 완료 돼야 다음 접속에 대한 작업을 진행하게 됩니다.

 

즉, 10개의 클라이언트가 동시에 1개 서버에 접속을 한 경우 1번째 클라이언트에 대한 작업이 완료되면 2번째 클라이언트에 대한 작업을 진행하고 완료되면, 3번째 클라이언트 작업 완료되면, 4번째 클라이언트 작업.... 이렇게 순차적으로 작업을 진행하게 되며 최종 10번째로 접속한 클라이언트는 앞에 9개의 클라이언트에 대한 작업이 끝날때 까지 대기를 해야 하는 형태가 됩니다. 거기다 각 클라이언트에 대한 작업시간이 언제끝날지 모른다면 뒤에 대기중인 클라이언트들은 한없이 대기할수 밖에 없는 상태가 되지요.

 

- 블록킹 소켓 + 멀티스레드 방식 설명

그래서 이러한 현상을 극복하기 위해 스레드를 사용하였습니다. 각 클라이언트들이 접속시 1개 클라이언트당 1개의 스레드를 생성하여 멀티스레드 방식으로 운용을 하게 됩니다. 스레드는 동시에(정확히는 아니지만..) 작업이 가능 하므로 클라이언트가 10개가 들어오던 20개가 들어오던 거의 동시에 작업이 이루어지게 되고 블록킹 소켓을 사용하지만 스레드의 장점을 활용한 방법이라 볼수 있습니다.

 

하지만, 이 방법도 완전한 방법이 아닙니다. 운영체제마다 스레드의 갯수가 제한(설정가능..)되어 있는데 만약, 제한된 스레드의 갯수보다 많은 클라이언트들이 접속해야 한다면 문제가 발생하게 됩니다. (가용성 부재)

뿐만 아니라, 스레드가 작동되기 위해 컨텍스트 스위칭이 계속적으로 발생하게 되는데 스레드가 많은면 많을수록 성능이 하락되어 최종에는 스레드를 사용하는 의미가 사라지게 됩니다. (성능하락)

 

- 논-블록킹 소켓 설명

위와 같은 문제점을 극복하기 위해 한개 스레드에서 여러 클라이언트의 작업을 번갈아가면서 작업을 하기 위한 모델을 만들었는데 그게 바로 논-블록킹 모델 입니다.

논-블록킹 소켓을 사용하면 접속한 클라이언트의 갯수와 상관없이 한개의 스레드에서 번갈아가면서 작업을 하게 되며 이벤트 방식과 흡사한 방식으로 작동됩니다.

 

3개의 클라이언트가 서버에 접속해 작업을 하는 경우 1번째 클라이언트가 보낸 데이터가 있다면 데이터를 받고 3번째 클라이언트에게 데이터를 전송할수 있는 상황인 경우 데이터를 전송하는 형태가 됩니다.

 

2. 그리고 클라이언트가 보통 30개 정도 붙고 끈임없이 데이터를 주고 받아야 한다면 둘중 어느게 안정적이고 빠른가요?

블록킹 소켓 + 멀티스레드 방식의 경우 스레드 갯수와 컨텍스트 스위칭과 관련된 단점이 있는 반면에 프로그램 제작하기가 상대적으로 쉽습니다. 클라이언트가 30개라면 스레드가 30개 정도 생성된다고 봐야 하는데 개인적으로 스레드 30개정도는 문제될 부분이 많지 않다고 생각됩니다. 만약, 30개보다 더 많은 클라이언트의 갯수가 접속해야 한다면 가용성이나 성능 부분을 위해 논-블록킹으로 작업해야 될겁니다.

논-블록킹 모델은 많은 장점이 있는데 불구하고 단점은 상대적으로 프로그램 작성하기가 힘듭니다.

그리고, 논-블록킹 모델의 경우도 분명 병목현상이 발생되는 지점이 있기에 서비스와 관련된 부분에 스레드를 사용해야하는등 신경써줘야 하는 부분들이 더 많습니다.

선택은 본인이 하겠지만 저라면 블록킹 소켓 + 멀티스레드로 가겠습니다.

아. 참고로 더 말씀드리지만 논-블록킹은 블록킹보다 상대적으로 가용성이 높지만 속도가 빠른것은 아닙니다. 서버가 대량의 클라이언트를 받아들이고 안정적인 서비스를 하고자 하는 경우 논-블록킹의 선택하는게 현명하지 않나 생각됩니다. 
  

표준 Java 코드 스타일

Posted by epicdev Archive : 2011. 9. 21. 04:48
코딩할때 지키도록 노력하자

http://java.sun.com/docs/codeconv/CodeConventions.pdf

'Archive' 카테고리의 다른 글

블록킹 소켓 vs 논 블록킹 소켓  (0) 2011.09.21
구글 안드로이드 코드 스타일  (0) 2011.09.21
Static 메소드에서 Synchronized 사용하는 방법  (0) 2011.09.21
HashMap 과 Hashtable의 차이  (0) 2011.09.21
Fail-Fast란?  (0) 2011.09.21
  

Static 메소드에서 Synchronized 사용하는 방법

Posted by epicdev Archive : 2011. 9. 21. 04:35
class Foo {
  public static synchronized void bar() {
      // Foo.class의 monitor를 사용한다
  }

  public static void bar2() {
      synchronized(Foo.class) {
          // Foo.class의 monitor를 사용한다
      }
}

'Archive' 카테고리의 다른 글

구글 안드로이드 코드 스타일  (0) 2011.09.21
표준 Java 코드 스타일  (0) 2011.09.21
HashMap 과 Hashtable의 차이  (0) 2011.09.21
Fail-Fast란?  (0) 2011.09.21
안드로이드에서의 Multithreading 예제  (0) 2011.09.21
  

HashMap 과 Hashtable의 차이

Posted by epicdev Archive : 2011. 9. 21. 03:06
출처: http://stackoverflow.com/questions/40471/java-hashmap-vs-hashtable

 There are several differences between HashMap and Hashtable in Java:
  1. Hashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.
  2. Hashtable does not allow null keys or values. HashMap allows one null key and any number of null values.
  3. One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for a LinkedHashMap. This wouldn't be as easy if you were using Hashtable.

'Archive' 카테고리의 다른 글

표준 Java 코드 스타일  (0) 2011.09.21
Static 메소드에서 Synchronized 사용하는 방법  (0) 2011.09.21
Fail-Fast란?  (0) 2011.09.21
안드로이드에서의 Multithreading 예제  (0) 2011.09.21
Java Heap에 대한 10가지 사항  (0) 2011.09.20
  
 «이전 1 2 3 4 5  다음»