목요일, 1월 24

Java 동기화 관련 키워드 정리




 Multi-Threading 에 동기화는 중요한 이슈입니다.

 이번 글은 Java에서 동기화를 사용할 때, 자주 등장하는 키워드를 정리해보고자 합니다.


 0. 키워드 정리 전에 앞서.
 이 글은 멀티 쓰레딩이나 동기화를 정리하려는게 아니고 키워드의 의미만 집고 넘어가려는 글입니다. 그러므로 어느 정도 기반 지식이 있으셔야 합니다.

 0-1. Atomic
 그런 측면에서 Atomic = 원자 연산에 대해서는 기본적으로 이해하고 계셔야 됩니다. 이 개념을 모르고 멀티쓰레딩이나 동기화를 논한다는 것 자체가 어이없는 일이라고 생각이 드니까요. 비유를 하자면 한글도 모르는 사람이 문법 따지는 격입니다.

 Atomic 연산이란 무엇이냐면, 1clock에 처리될 것을 보장하는 연산입니다.
 예를 들면,

 int x = 1;
 과 같은 연산은 cpu에서 보면

 xor [x], 1
 과 같은 명령어로 번역될 수 있고, 이는 1clock에 처리됩니다.
 만약 위의 코드가

 mov eax, 1
 mov [x], eax
 와 같은 식으로 번역된다면 mov eax,1 까지 처리된 상태에서 다른 쓰레드가 eax에 다른 값을 세팅해놓을 경우 [x]에는 엉뚱한 값이 들어가게 됩니다. 그래서 동기화 이슈에서 atomic 연산은 가장 기초적인 개념입니다.



 1. Volatile

 가장 많은 분이 헤깔려하고 이해하지 못하면서 대충 이해하는 키워드가 이 Volatile이 아닌가 싶습니다.

 Volatile 키워드의 의미는 "컴파일러나 옵티마이저가 특정 메모리에 대해서 최적화나 캐쉬등의 작업을 하지 말아라." 라고 주문해 놓는 것입니다.

 0.1 Atomic편에서 말씀드렸듯 원자 연산은 필수적인 요소 입니다.

 만약 Volatile 을 지시하지 않는다면, Java의 컴파일러 혹은 runtime optimizer는 해당 변수의 대입등을 최적화 하기 위해서 여러가지 수를 쓰게 됩니다. 이 과정에서 만약 xor [x], 1 과 같은 int x = 1. x에 1을 넣는 연산이 일단 레지스터나 캐쉬 같은 보다 속도가 빠른 공간에 1을 두고 추가 연산 후에 x에 값을 대입하려고 할 수 있습니다.

 이럴 경우 마찬가지로 동기화 이슈가 발생할 수 있습니다. 최적화 된 코드가 x에 1이 대입될 것을 보장해주지 않기 때문입니다. volatile 키워드로 지정된 변수와 관련된 대입, 연산 등의 동작은 반드시 해당 메모리 공간을 가지고 작업을 하게 됩니다.




 2. Synchronized


 Synchronized는 임계영역입니다.
 이는 말 그대로, 두 개 이상의 쓰레드가 동시에 접근하는 것을 막는다는 뜻입니다.














webview - viewport 사용하여 다해상도에서 동일한 웹페이지 보여주기






안드로이드 기기들의 해상도 파편화는 웹뷰를 사용할 때도 똑같이 문제가 됩니다. 만약 고정된 사이즈를 갖는 콘텐츠를 웹페이지 형태로 보여주고자 하면, 해당 문제로 골치를 꽤나 썩게 됩니다.


이런 문제를 해결하기 위해서는 webkit 엔진에서 사용하는 viewport meta-tag를 사용해야 합니다. 같은 webkit 이므로 ios에서도 동일하게 적용됩니다.




webview.getSettings().setUseWideViewPort(true);
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);

Format df = new DecimalFormat("##.##");

int contentWidth = 720; //content web page width
int deviceWidth = metrics.widthPixels;
String viewport = null;
if ( contentWidth > deviceWidth ){
 String scale = "1.0";
 scale = df.format( (float)deviceWidth / (float)contentWidth );
 contentWidth = deviceWidth;
 viewport = "";
} else {

 viewport = "";
}

Log.i("TEST", viewport);
data += viewport;
wv.loadDataWithBaseURL("file:///android_asset/", data , "text/html", "UTF-8", "");

        
해당 코드는 android_asset 에 넣어놓은 html 파일을 로드해오는 코드입니다.

자세한 사항은 여기 참고하시고 -

Targeting Screens from Web Apps


왜 이런 일이 발생하는지를 간단히 요약해드리겠습니다.


안드로이드에서 default dpi 값은 160 입니다. medium-dpi 라고 말하는 이 값의 뜻은
dpi :dots per inch 약자 입니다.

인치당 얼마의 dots 가 존재하느냐? 이런 의미지요.

안드로이드의 해상도는 이 dpi 값이 160일 때를 기본형, 즉 1로 처리합니다.

그러므로 만약 해상도가 480 x 800 인 기기가 있다고 했을때, 이는 실제로 화면 픽셀이 480x800인 것이 아니고, 기기 해상상도에 dpi 값이 곱해진 값입니다.

즉, 기기의 dpi 가 240 이라고 한다면. 이는 240/160 = 1.5 가 곱해진 해상도입니다.
이에 따른 실제 기기의 해상도는  320x533 인 것 입니다.

이런 상황에서 480px 800px 의 웹페이지를 그냥 로드하려고 하면 당연히 화면이 넘쳐나게 됩니다. 때문에 viewport를 통해 실제 웹페이지를 그려놓을 곳의 size를 정해주는 것입니다.