[Java] SynchronizedCollections vs ConcurrentCollections[Java] SynchronizedCollections vs ConcurrentCollections

Posted at 2013. 8. 17. 19:04 | Posted in 개발이야기

SynchronizedCollections(동기화된 컬렉션)과 ConcurrentCollections(병렬 컬렉션)



동기화된 컬렉션 클래스는 컬렉션의 내부 변수에 접근하는 통로를 일련화해서 스레드 안전성을 확보했다. 하지만 이렇게 만들다 보니 여러 스레드가 한꺼번에 동기화된 컬렉션을 사용하려고 하면 동시 사용성은 상당 부분 손해를 볼 수 밖에 없다. 하지만 병렬 컬렉션은 여러 스레드에서 동시에 사용할 수 있도록 설계되었다.

ConcurrentMap에는 put-if-absent, replace, condition-remove 등을 정의하고 있다.


기존에 사용하던 동기화 컬렉션 클래스를 병렬 컬렉션으로 교체하는 것만으로도 별다른 위험 요소 없이 전체적인 성능을 상당히 끌어 올릴 수 있다.

<에이콘 - 자바 병렬 프로그래밍(p.137) 발췌>


동기화되지 않은(unsynchronized) 컬렉션

- List: ArrayList, LinkedList

- Map: HashMap

- Set: HashSet

- SortedMap: TreeMap

- SortedSet: TreeSet

- Since JDK 1.2

- 문제점: Thread Safe하지 않다.


동기화된(synchronized) 컬렉션

- Vector, Hashtable, Collections.synchronizedXXX()로 생성된 컬렉션들

- Since JDK 1.2

- 문제점: Thread Safe하나, 두개 이상의 연산을 묶어서 처리해야 할 때 외부에서 동기화 처리를 해줘야 한다. (Iteration, put-if-absent, replace, condition-remove 등)


병렬(concurrent) 컬렉션

- List: CopyOnWriteArrayList

- Map: ConcurrentMap, ConcurrentHashMap

- Set: CopyOnWriteArraySet

- SortedMap: ConcurrentSkipListMap (Since Java 6)

- SortedSet: ConcurrentSkipListSet (Since Java 6)

- Queue 계열:ConcurrentLinkedQueue

- Since Java 5

- 특이사항: Concurrent(병렬/동시성)이란 단어에서 알 수 있듯이 Synchronized 컬렉션과 달리 여러 스레드가 동시에 컬렉션에 접근할 수 있다. ConcurrentHashMap의 경우, lock striping 이라 부르는 세밀한 동기화 기법을 사용하기 때문에 가능하다. 구현 소스를 보면 16개의 락 객체를 배열로 두고 전체 Hash 범위를 1/16로 나누어 락을 담당한다. 최대 16개의 스레드가 경쟁없이 동시에 맵 데이터를 사용할 수 있게 한다. (p.350)

반대로 단점도 있는데, clear()와 같이 전체 데이터를 독점적으로 사용해야할 경우, 단일 락을 사용할 때보다 동기화 시키기도 어렵고 자원도 많이 소모하게 된다. 또한, size(), isEmpty()같은 연산이 최신값을 반환하지 못할 수도 있다. 하지만 내부 상태를 정확하게 알려주지 못한다는 단점이 그다지 문제되는 경우는 거의 없다.


※ Queue, BlockingQueue 인터페이스는 Java 5에서 추가되었다. (Deque, BlockingDeque는 6에서 추가되었다.)

※ Synchronized 컬렉션은 객체 자체에 락을 걸어 독점하게되고, Concurrent 컬렉션은 객체 자체 독점하기가 쉽지 않은 단점이 있지만, 장점이 훨씬 더 많다. Concurrent 컬렉션은 컬렉션 전체를 독점하기 위해서는 충분히 신경을 기울여야 한다.

※ Hash를 기반으로 하는 컬렉션은 hashCode()의 해시값이 넓고 고르게 분포되지 못하면 한쪽으로 쏠린 해시 테이블을 사용하게 되는데, 최악의 경우는 단순한 Linked List와 거의 동일한 상태가 될 수 있다.


//

[Java] 병렬 프로그래밍에서 잊지말아야 할 조언들[Java] 병렬 프로그래밍에서 잊지말아야 할 조언들

Posted at 2013. 8. 17. 18:04 | Posted in 개발이야기




여러 스레드가 클래스에 접근할 때, 실행 환경이 해당 스레드들의 실행을 어떻게 스케줄하든 어디에 끼워 넣든, 호출하는 쪽에서 추가적인 동기화나 다른 조율 없이도 정확하게 동작하면 해당 클래스는 스레드 안전하다고 말한다.(p.48)


상태 없는(Stateless) 객체는 항상 스레드 안전하다. (p.49)


종종 단순성과 성능이 서로 상충할 때가 있다. 동기화 정책을 구현할 때는 성능을 위해 조급하게 단순성(잠재적으로 안전성을 훼손하면서)을 희생하고픈 유혹을 버려야 한다. (p.65)

일례로, 한 클래스의 멤버 변수를 public으로 노출하여 사용한 경우, 이 변수가 어디서 어떻게 쓰일지 알 수 없으므로, 이 클래스를 Thread safe하게 만들기 위해서는 해당 변수를 사용한 곳을 모두 조사해봐야 한다. 그러나 private으로 숨기고 getter/setter를 사용한 경우 method 레벨에서 동기화를 구현하면 쉽게 Thread Safe한 클래스가 될 수 있다.

따라서, 번거럽더라도 getter/setter를 쓰는 것이 좋다. 너무도 명백하게 내부적으로 잠시 사용하는 inner class 같은 것들까지 getter/setter를 쓰는건 과한 것일 수도 있으니 적절히 판단해서 사용하자.

동기화와 캡슐화에 대한 이야기는 책의 여기저기에서 다른 표현들로 등장한다.


복잡하고 오래 걸리는 계산 작업, 네트웍 작업, 사용자 입출력 작업과 같이 빨리 끝나지 않을 수 있는 작업을 하는 부분에서는 가능한 한 락을 잡지 말아라. (p.65)



(계속)




//

[GWT] eclipse에 GWT project import 하기[GWT] eclipse에 GWT project import 하기

Posted at 2013. 8. 17. 15:06 | Posted in 개발이야기

GWT 프로젝트 디렉토리를 이동하려고 다른 디렉토리에 옮겨놓은 후

다음과 같은 방법으로 다시 불러올 수 있다.


(1) .project 파일이 있는 경우: Import > General > Existing Projects into Workspace

(2) .project 파일이 없는 경우

  New > Other... > GWT Designer > Model

  


  Next 후에 project Root 디렉토리를 선택하면 .project 파일이 없어도 깔끔하게 import 된다.




//

Clock & Timer resolution(시간, 타이머 해상도)Clock & Timer resolution(시간, 타이머 해상도)

Posted at 2013. 1. 30. 15:28 | Posted in 개발이야기

출처: https://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks


clock에는 다음 2가지가 있다.

  • absolute clock (the time-of-day clock, with a low resolution)
  • relative clock (some kind of "high-resolution" counter from which a "free-running" time can be calculated)


현대 컴퓨터에서는 clock과 timer는 큰 차이가 있다.

The resolution of clocks and timers in modern computers is typically very different.

timed events are triggered by operating system controlled interrupts that are normally much more coarse grained (typically 10ms)

Further, systems often have a quite different resolution for the time-of-day clock (often low resolution of 10ms or worse) and the free-running relative clock (microseconds or better), because they are actually derived from quite different pieces of hardware.


absolute clock(time-of-day)는 자바에서 System.currentTimeMillis()로 구현된다.

(System.currentTimeMillis() = 'time-of-day' clock. update resolution is same as the timer interrupt(eg. 10ms).)

The absolute "time-of-day" clock is represented by the System.currentTimeMillis() method, that returns a millisecond representation of wall-clock time in milliseconds since the epoch. As such it uses the operating system's "time of day" clock. The update resolution of this clock is often the same as the timer interrupt (eg. 10ms), but on some systems is fixed, independent of the interrupt rate.


relative-time clock 은 자바에서 System.nanoTime()으로 구현된다. high-resolution이다.

The relative-time clock is represented by the System.nanoTime() method that returns a "free-running" time in nanoseconds.

The nanoTime method uses the highest resolution clock available on the platform, and while its return value is in nanoseconds, the update resolution is typically only microseconds.

However, on some systems there is no choice but to use the same clock source as for currentTimeMillis() - fortunately this is rare and mostly affects old Linux systems, and Windows 98.


자바 타이머 관련 클래스의 해상도.

  • The java.util.Timer and java.util.TimerTask - use of currentTimeMillis()
  • Java 5.0 ScheduledThreadPoolExecutor (STPE) - use of nanoTime()



//

[mybatis] selectOne vs selectList[mybatis] selectOne vs selectList

Posted at 2012. 12. 21. 10:26 | Posted in 개발이야기

org.mybatis.spring.SqlSessionTemplate

- selectOne

  • 쿼리의 결과가 없으면 null을 반환한다. 또한, 쿼리의 결과로 레코드가 하나만 나와야 한다.
  • DB에 하나의 레코드만 있는 경우 사용. 그렇지 않으면 org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException 이 발생한다.

- selectList

  • 쿼리의 결과를 List<E>로 반환한다. 결과가 없으면, 빈 List를 반환한다.
  • selectList()가 null을 반환하지는 않는다.



//

curl 활용하기curl 활용하기

Posted at 2012. 12. 21. 10:02 | Posted in 개발이야기

<post 호출>

curl -d @data.txt http://localhost:8080

curl -d "12345" http://localhost:8080

curl -X POST -d "12345" http://localhost:8080

curl -H "Accept: application/json" -H "Content-Type: application/json" --fail -d @data.txt http://localhost:8080



<file download>

curl -O http://redis.googlecode.com/files/redis-2.6.9.tar.gz

curl -o taglist.zip http://www.vim.org/scripts/download_script.php?src_id=7701


wget http://redis.googlecode.com/files/redis-2.6.9.tar.gz

wget -O taglist.zip http://www.vim.org/scripts/download_script.php?src_id=7701


//

grinder 사용팁grinder 사용팁

Posted at 2012. 9. 16. 15:23 | Posted in 개발이야기

grinder-3.8 버전 사용.

(이리 저리 해보고 해결한 것들만 메모함.)


grinder에 있는 jython 보다 높은 버전 사용하고 싶은 경우,

--> grinder/lib/jython-xxx.jar 를 빼고, property 및 실행 스크립트에 jython 설치 경로 및 classpath에 지정해 줬더니 되더라..

요렇게..

JYTHON_HOME=/usr/share/jython

JYTHON_CONFIG="-Dpython.home=$JYTHON_HOME -Dpython.path=$JYTHON_HOME/Lib"

CLASSPATH=$CLASSPATH:$JYTHON_HOME/jython.jar

java -cp $CLASSPATH $JYTHON_CONFIG net.grinder.Grinder


symbolic link 파일을 dist위치에 두고 배포하니 Agent에서 어러남.


agent 실행시 필요 jar 파일 미리 배포해둬야 한다. classpath에도 미리 잡아놔야 하고..

--> classpath에 ./lib/*.jar 와 같은식으로는 안먹네.. 모두 나열해주니 됨.


grinder.logger --> (grinder.hostID)-0.log 파일에 기록됨.


agent terminal에서 확인하려면 stdout으로 출력해서 보라.


grinder.statistics.delayReports = 1 는 TestRunner __init__ 에서 한번만하고, on/off 하지 않는다.


jython 스크립트 맨 밑줄에 공백 라인 한줄 넣어야 하더라..


jython 스크립트에 한글 쓰니 non-ascii character가 있다고 나불나불..

--> 첫째줄에 요렇게 넣어주면..

# _*_ coding: utf8 _*_



참고하기 좋은 글: http://www.cubrid.com/zbxe/71339

//

Authentication(인증) vs Authorization(권한)Authentication(인증) vs Authorization(권한)

Posted at 2012. 9. 16. 13:57 | Posted in 개발이야기

자주 헷깔리는 용어.


Authentication(인증)

    자격을 부여 (the mechanism whereby systems may securely identify their users)

    * who ?


Authorization(권한)

    자격이 있는 경우 사용할 수 있는 범위 (the mechanism by which a system determines what level of access a particular authenticated user should have to secured resources controlled by the system)

    * access resource ?

    * perform operation ?


참고: http://www.duke.edu/~rob/kerberos/authvauth.html

//

[openssl] OpenSSL API를 이용한 보안 프로그래밍[openssl] OpenSSL API를 이용한 보안 프로그래밍

Posted at 2012. 9. 16. 13:42 | Posted in 개발이야기

OpenSSL API를 이용한 보안 프로그래밍, Part 1: API의 개요

http://www.ibm.com/developerworks/kr/library/l-openssl.html


OpenSSL API를 이용한 보안 프로그래밍, Part 2: 안전한 핸드쉐이크(handshake)

http://www.ibm.com/developerworks/kr/library/l-openssl2.html


OpenSSL API를 이용한 보안 프로그래밍, Part 3: 보안 서비스 제공하기

http://www.ibm.com/developerworks/kr/library/l-openssl3.html

//

[openssl] command line sample[openssl] command line sample

Posted at 2012. 9. 16. 13:41 | Posted in 개발이야기

DES encript/descript

$ openssl enc -e -des -in aaa.c -out bbb.pem

$ openssl enc -d -des -in bbb.pem -out 111.c

$ diff aaa.c 111.c


Base64 encript/descript

$ openssl enc -e -base64 -in aaa.c -out bbb.b64

$ openssl enc -d -base64 -in  bbb.b64 -out 111.c

$ diff aaa.c 111.c


DES+Base64 encript/descrip

$ openssl enc -e -des -base64 -in aaa.c -out bbb.pem

$ openssl enc -d -base64 -des -in bbb.pem -out 111.c

$ diff aaa.c 111.c

//