달력

1

« 2021/1 »

  •  
  •  
  •  
  •  
  •  
  • 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
  •  
  •  
  •  
  •  
  •  
  •  
2013. 3. 25. 20:12

Android 의 WebView pinch zoom 없애기 Android2013. 3. 25. 20:12

까먹을까봐 올린다;;

웹뷰의 onTouchEvent 를 Overriding 해서 처리한다.

@Override
 public boolean onTouchEvent(MotionEvent event) {

if (event.getPointerCount() > 1) {
   getSettings().setBuiltInZoomControls(true);
   getSettings().setSupportZoom(true);
  } else {
   getSettings().setBuiltInZoomControls(false);
   getSettings().setSupportZoom(false);
 }
  return super.onTouchEvent(event);
 }

Posted by maruldy

댓글을 달아 주세요

2012. 11. 20. 17:00

Java volatile 키워드 정리. Java2012. 11. 20. 17:00

Java Language Specification 에 나온 내용을 기반으로 설명함.

 

8.3.1.4 volatile Fields


The Java programming language allows threads to access shared variables (§17.1).
As a rule, to ensure that shared variables are consistently and reliably updated, a
thread should ensure that it has exclusive use of such variables by obtaining a lock
that, conventionally, enforces mutual exclusion for those shared variables.
The Java programming language provides a second mechanism, volatile fields,
that is more convenient than locking for some purposes.
A field may be declared volatile, in which case the Java Memory Model ensures
that all threads see a consistent value for the variable (§17.4).8.3.1 Field Modifiers CLASSES

It is a compile-time error if a final variable is also declared volatile.

 

일단 위를 번역, 의역해보자..

 

자바는 thread 들이 공유된 변수에 접근하는 것을 허용한다.
일반적으로는(Java 뿐 아닌 다른 언어에 대해서도), Thread 간에 공유된 변수들의 일관성 있고 확실한 업데이트(데이터의 변경)를 하기 위해,

thread 는 이러한 변수들을 독점적으로 얻기 위한 방법으로 mutex 를 적용하곤 했다.

(여러 Thread 가 같은 변수에 한번에 접근하지 않기 위해서 Mutual Exclusion 처리를 해주고 있다는 말임.)


자바에서는 이에대해 좀더 쉬운 방법인 volatile field 라는 또 다른 방식을 제공한다.
field 가 volatile 을 이용해서 선언이 되었을 경우에,

자바 메모리 모델은 해당 변수에 대해 모든 쓰레드가 일관된 값을 사용할 것을 보장한다.
만약에 final 과 volatile 혼용해서 쓴다면 컴파일 시점에 오류가 발생하게 된다.

 

좀더 자세히 살펴보자..

 

1. Thread 간에 변수가 공유되면, Thread 는 그 값을 복사해 놓은 후, 복사한 값을 참조해서 사용한다.


Java 에서는 Thread 를 사용할 때 performance 향상을 위해 해당 변수의 값을

Thread 가 사용하는 메모리 영역에 caching 하는 것을 허용한다.


예를 들면, ThreadA 와 ThreadB 라는 두개의 쓰레드가 foo 라는 변수를 바라보고 있을 때,

foo 라는 변수를 각각 쓰레드의 로컬 메모리영역에 caching 해서 사용을 하는 식이 된다.


따라서, ThreadA 가 foo 라는 변수의 값을 "abc" 에서 "def" 로 바꾼다고 하더라도

어느 시점에는 ThreadB 는 여전히 "abc" 라는 값을 가지고 있을 수 있다.

(간단한 테스트 코드로도 확인 가능하다.)

 

이러한 문제를 극복하기 위해 volatile 이라는 키워드를 사용해서 변수를 선언하게 되면,

각 Thread 들은 foo를 caching 하지 않고, foo를 사용할 때마다 메인메모리 영역의 foo 를 바라본다.

위 글을 읽다 보면 final 과 volatile 은 같이 사용이 불가능 하다는 구문이 나오는데,

내 생각에는 final 은 변수가 바뀌지 않는다는 것을 전제도 하는 키워드이지만,

volatile 은 변수가 바뀌는 것을 전제로 하는 키워드이기 때문에 둘을 혼용해서 쓸 수 없는 것 같다.

2. Thread 간에 공유된 변수에 한 Thread 가 접근하면, 다른 Thread 는 접근하지 못한다.

 

예를들면 4바이트 이상의 변수인 long 을 변경한다고 했을 때, 앞 4바이트와 뒤 4바이트를 나눠서 변경한다.

예를들면 long 값을 21521542 에서 463634110 으로 변경시킨다고 했을 때, 앞 4바이트를 변경하고 뒤 4바이트를 변경한다.

 

이게 어떤 결과를 야기시킬 수 있냐면, 

여러 ThreadA 가 long 값을 변경시키고 있는 와중에도 ThreadB 가 long 에 접근하면,

ThreadB 는 21521542 도 아니고 463634110 도 아닌 전혀 다른 값을 출력할 수 있다는 얘기다.

 

그 값의 정체는 앞4바이트 값은 바뀌고 있는데 뒤 4바이트는 예전의 값인, 두 숫자가 혼합된 값이 나올수도 있다는 얘기다.

(int 같은 경우에는 어차피 4바이트 변수니까 해당사항이 없긴 하다.)

 

내가 알아본 volatile 키워드의 효과는 위에 적은 두가지다.

까먹지 말고 잘 사용합시다~ :)

Posted by maruldy

댓글을 달아 주세요

일전에, 공개되지 않은 WebView 의 Method 인 setEmbeddedTitleBar() 메소드를 사용하는 법을 알아다.

 

두가지 정도 내용을 더 추가하자면,

1. 화면 하단에 (-/+) 같은 줌 버튼이 생기는데, 이게 미관상 좋지 않다.

이 부분을 없애려면 Webiew 를 상속받아서 onTouchEvent 를 Overriding 하면 된다.

@Override
 public boolean onTouchEvent(MotionEvent motionEvent) {
  final int eventAction = motionEvent.getAction();
  if (eventAction == MotionEvent.ACTION_DOWN ||
   eventAction == MotionEvent.ACTION_POINTER_DOWN ||
   eventAction == MotionEvent.ACTION_POINTER_1_DOWN ||
   eventAction == MotionEvent.ACTION_POINTER_2_DOWN ||
   eventAction == MotionEvent.ACTION_POINTER_3_DOWN ||
   eventAction == MotionEvent.ACTION_MOVE) {
   if (motionEvent.getPointerCount() > 1) {
    getSettings().setBuiltInZoomControls(true);
    getSettings().setSupportZoom(true);
   } else {
    getSettings().setBuiltInZoomControls(false);
    getSettings().setSupportZoom(false);
   }
  }
  return super.onTouchEvent(motionEvent);
 }

 

2. TitleBar 를 포함한 WebView 의 영역과 별개의 영역에 Layout 을 구성하면, 해당 WebView 의 Zoom 등에 영향을 받지 않는다

 

이정도를 적용 시키니 한층 화면 보기가 좋아졌다.

 

Posted by maruldy

댓글을 달아 주세요

TimeZone.getDefault().getOffset(기준시간); 로 값을 얻어오면
offset 을 얻을 수 있는데 이게 역시 currentTimeMillis 로 들어온다.

이걸 기준시간에 더해버리면 현재 지역의 시간을 얻을 수 있다.

Posted by maruldy

댓글을 달아 주세요

2011. 1. 5. 14:31

Singleton Pattern Design Pattern2011. 1. 5. 14:31

Application 이 실행되는 동안 단 1개의 Instance 만을 사용하고 싶을 때 사용하는 방법이 있다.
보통은 이걸 Singleton Pattern 이라고 하는데, 코드는 아래와 같다. 코드는 계속 개선된다.
Singleton 방식으로 관리할 클래스의 이름은 Context 라는 클래스라고 가정하자


public class Context {

  private static Context context;

  //다른 클래스에서 new Context() 를 이용한 Context 클래스의 인스턴스 생성을 막는다.
  private Context() { } 
  public static Context getInstance() {
    if(context == null) {
      context = new Context();
    } // end if
    return context;
  } // end getInstance()
}

위와 같은 Singleton 설계방법에는 위험성이 따르게 된다.
Multi-Thread 환경에서 객체를 2개 이상 만들어버릴 수 있기 때문이다. 
어제까지, 이에대한 해결책은 3가지 정도만 있다고 알고 있었다.

1. private static Context context = new Context();
   단점 : 쓸데없는 메모리를 차지하게 될 수 있다는 단점이 있다.

2. synchronized 키워드를 이용해서 동기화를 시키는 방법이 있다.
   2-1. synchronized 를 이용해서 getInstance() 메소드 자체를 동시화 시킨다.
        public static Context getInstance() -> public static synchronized Context getInstance()
        해당 메소드에 대해서 성능면에서 '심각한' 손해가 있다고 한다.
   2-2. DCL (Double Checked-Locking) 기법을 사용한다.
        인스턴스 생성을 인스턴스가 필요한 시점까지 최대한 늦출수 있다. 1번의 단점은 해소된다.
        처음 객체를 만들때만 동기화가 된다. 2번의 단점도 어느정도 해소시킬수 있다.
        자세한 방법은, volatile(이 키워드가 생소하다면 여기 를 참조) 키워드를 레퍼런스 변수에 걸어둔다.
        
        private volatile static Context context; <-- 와 같이 선언한 후에,
        
        public static Context getInstance() {
          if(context == null) {
            synchronized(Context.class) {
              if(context == null) {
                context = new Context();
              } // end if
            } // synchronized block
          } // end if
          return context;
        } // end getInstance()
        
        적느라 힘들었음.ㅠ; 
        위와같은 코드를 getInstance 에 대체시키면, 객체를 만들때만 동기화 시키므로 하나의
        객체만 만들어서 관리한다는 설계의도에 빗나가지 않으며, 이후에는 동기화가 필요없게 된다.
        하지만 단점이 있다. volatile 키워드가 1.5 아래버전들에서는 완벽한 작동을 보장하지 않는다.


나는 여기까지가 전부인줄 알고 장단점을 고려해서 '돌려막기' 식으로 하면 되겠지 라는 생각을 했고,
어제 nhn i&s 신입 면접에서 마치 DCL 기법까지가 전부인것처럼 말했다. (ㅠㅠ)

하지만 오늘 인터넷을 검색해다가 보니, 다른 방법이 있었다. 
synchronized 키워드를 사용하지도 않고, java 버전에 구애되지도 않는 기법이다.
내부에 클래스를 하나 더 선언하면 된다고 한다.
구체적인 구현 코드는 아래와 같다.

public class Context {

 
private Context() {
  }

  private static class SingletonHolder {
   
private static final Context INSTANCE = new Context();
 
}
 
  public static Context getInstance() {
    return SingletonHolder.INSTANCE;
  }
}

.... olleh!! ㅠㅠ
왜 하필 이런건 면접본 다음날 알게되는것인가!! OTL....
내가 부족한탓이라고 생각하고 공부를 멈추지 말아야 하겠다...
.. 그런데 토익점수 없는 나오서는 더이상 서류통과 되는곳이 없을까봐 두렵다...-_-;

Posted by maruldy

댓글을 달아 주세요

테스트코드에 애노테이션을 추가.

@Test(expected = 예외클래스)
public void exceptionTest() ... {
...
}

위와같이 해주고, 테스트하는 메소드에서 예외 발생을 던져줄때 테스트가 성공

야호!
Posted by maruldy

댓글을 달아 주세요

2010. 8. 18. 15:54

maven 에 ojdbc 추가하기 Maven2010. 8. 18. 15:54

공부하면서 maven 써봐야겠다고 생각은 했는데 이제야 써봄..
아래는 ojdbc 를 추가해주기 위한 방법임..

maven 으로 프로젝트를 만들면 pom.xml 이 생기는데
이 xml 파일의 최상위 노드는 <project> 이다.
그 하위노드로 <repositories>, <dependencies>, <build> 등이 있다.
또 그 하위노드로 이어지는데 쓰게되면 알게될것이다. -_-;;;

maven 을 이용해서 ojdbc 를 추가해주려면 pom.xml 을 열어서 편집해줘야 한다.
메이븐은 프로젝트에 넣을 라이브러리들을 pom.xml 파일 수정을 하면서 편하게 관리해줄수 있다.
ojdbc를 추가하는 방법도 간단하다.

<repositories> 의 하위노드에

<repository>
     <id>mesir-repo</id>
     <url>http://mesir.googlecode.com/svn/trunk/mavenrepo</url>
</repository>

이걸 삽입한다.

그리고

<dependencies> 의 하위노드에는

<dependency>
    <groupId>com.oracle</groupId>
    <artifactId>ojdbc14</artifactId>
    <version>10.2.0.4.0</version>
</dependency>

이걸 삽입하면 된다.

편하다 ㄷㄷ;;;;
메느님 만세!

너 말고 -_-




TAG Java, Maven
Posted by maruldy

댓글을 달아 주세요

2010. 3. 22. 20:39

Delegation Java2010. 3. 22. 20:39

.Net 에서는 Delegation 을 지원해준다고 하던데 .Net 은 아직 공부 안해서 잘 모르겠다..
Java 에서는 Delegation 을 명시적으로(키워드로) 원하지는 않는다.

Java 에서 구현하는 Delegation은

직접 A 클래스를 상속받지 않고서 그 클래스의 기능을
B 클래스에서 사용 가능하도록 A 클래스의 객체를 포함시킨다.(Composition)

B 클래스에서는, 사용하고싶은 A클래스의 메소드를 B 클래스 안에 구현해놓고 그것을 사용하기만 하면
결과적으로 메소드를 통한 인터페이스는 상속과 동일하게 된다. 

결과적으로 필요한것만 그때그때 사용할 수 있다는 점에서 더 강력한 기능을 할 수 있게 된다.

그런데.. 궁금한게 갑자기 생겼는데, 팀 프로젝트로 진행할때 이걸 쓸 일이 있을까?
interface 를 이용하는것과 별반 다를바가 없어보이는데..
.....에라 일단 알고 보는거다.. -_-; 알아서 나쁠거 없잖아.. ㅜ.ㅜ;; 나중에 이사람 저사람 물어보지 머..

..생각해봤는데 interface 와 이것과는 많은 차이가 있네... 아..이래서 머리나쁘면 고생..ㅠㅠ

Posted by maruldy

댓글을 달아 주세요

2010. 3. 17. 18:49

Composition 과 Inheritance Java2010. 3. 17. 18:49


Composition 과 Inheritance 의 차이는,

Class Father {
   public void gaming() {
      System.out.println("exciting!");
   }
}

Class Son extends Father {
   @Override
   public void gaming() {
      System.out.println("lol!!!");
      super.gaming();
   }
   public static void main(String[] args) {
      Son son = new Son();
      son.gaming();
   }
}
결과:
lol!!
exciting!

이렇게 사용하는것이 상속이고,

Composition 은 TIJ 로 공부하다가 이 말이 나오길래.. 뭔가 했더니..
별다른거 없었네..ㅜ.ㅜ;

Class Father {
   public void gaming() {
      System.out.println("exciting!");
   }
}

Class Son {
   public static void main(String[] args) {
      Father father = new Father();
      father.gaming();
   }
}

처럼 클래스에서 다른 클래스의 객체를 생성해서 사용하는것이 Composition..
Posted by maruldy

댓글을 달아 주세요

2010. 3. 17. 16:08

초기화와 static.. Java2010. 3. 17. 16:08

공부했던것 중에 중요한 부분을 Blog 에다가 적어놓으면 왠지 안잊어먹을것 같고,
실제로도 적으면서 좀더 정리를 잘 시킬수 있어서 좋은것 같다.
그러니까... 나의 적은 게으름이다!!! ;;

전에 Java 를 공부할 때 static 의 경우에는 조금 특별하게 생각해야 한다고 공부했는데,
이번에 다시 책을 보면서 공부하는 도중에 static 이 눈에 띄길래 천천히 읽어보았다.
초기화 시에, static 필드로 참조되는 객체에 대해서 어떤점을 주의해야 할까 읽어보니까,

1. non-static 객체가 static 객체보다 먼저 정의되어 있더라도, static 객체가 먼저 초기화된다.
2. static 객체는 처음 한번만 초기화된다.

의 두가지가 초기화와 관련해서 눈에 가장 먼저 들어왔고..

접근제한자와 static 을 이용한 Singleton 패턴을 사용할때도 눈에 들어왔다.
Singleton 패턴은... 에.. 나중에 Design Pattern 카테고리에서 한방에 패턴들 모아서 정리를..^^; 
Posted by maruldy

댓글을 달아 주세요