[완료]자바 스레딩 arraylist 동시 사용

system77의 이미지

자바 프로세스 안에서 두개의 스레드가

A 스레드는 끊임없이 arraylist에 put 을하고

B 스레드는 끊임없이 arraylist에 get 을 합니다.

두쓰레드는 arraylist에 대한 lock이걸리면 안됩니다.

이렇게 프로그래밍하면 오류는 안나는건가요?

A 스레드가 쓰는 도중 B 스레드가 읽는다면 메모리 오류가 없는지 알고싶습니다.

addnull의 이미지

ArrayList 는 thread-compatible 이기 때문에,
(참고 http://www.ibm.com/developerworks/java/library/j-jtp09263/index.html )

읽기만 하는 쓰레드와 쓰기만 하는 쓰레드, 단 두 개만 있다고 해도 예측할 수 없는 문제가 발생할 수 있습니다.
예를 들면 쓰기(put)가 완료되지 않은 부분을 읽기(get) 시도하는 문제죠.
(제가 ArrayList 내부 구조를 모르기 때문에 이 예시가 정확한 문제 사례가 아닐 수도 있습니다.)

참고로 Vector 는 thread-safe 이기 때문에 질문자께서 말씀하신 구조에 더 적합할 것 같습니다.
물론 읽기 전용 쓰레드에서는 현재 데이터가 하나라도 존재하는지(isEmpty)는 확인한 후에 get 해야겠죠 :)

익명 사용자의 이미지

Vector는 "두쓰레드는 arraylist에 대한 lock이걸리면 안됩니다." 는 조건을 만족할 수 없습니다.

addnull의 이미지

thread-safe 라는건
lock을 걸지 않은 상태에서 여러 쓰레드가 해당 자료구조의 데이터 수정(add, remove, put, get 등..)을 해도 안전하다는 의미입니다.

예를 들면 5byte 데이터를 쓰고 읽는 작업이 두 쓰레드에서 따로 행해질때,

thread-safe일 경우에 5byte가 온전히 다 쓰여지거나 읽혀지는게 보장되는데,

thread-safe가 보장 안 되면,
쓰는 작업이 5byte 중에 2~3byte만 완료된 상황에서도 다른 쓰레드의 읽기 작업이 실행될 수 있습니다.

질문자께서 원하시는 상황이 명시적인 lock이 없는 상황에서
하나의 쓰레드는 get만 다른 하나의 쓰레드에서는 put만 하시고 싶으시다면
thread-safe 자료구조를 쓰시는게 맞을 것 같습니다 :)

addnull의 이미지

방금 댓글 달고 다시 생각해보니

저는 "synchronized 키워드를 사용한 explicit lock을 사용하지 않겠다"라는 의미로만 생각하고 이야기했습니다.

혹시 thread-safe 자료구조에서 사용하는 implicit lock도 없어야한다고 생각하신 거라면,
그런 조건에서 안전한 작업을 보장하는 방법은 없다고 생각됩니다.

cleol의 이미지

질문자께서 locking 이라고 표현하신 것은 아무래도 blocking 을 말씀하시는 것 같습니다.
위에 neocoin 님이 말씀하신 CopyOnWriteArrayList 가 한 가지 해결책입니다.
read 쓰레드가 한 개, write 쓰레드 한 개 라면 아무런 locking 이 필요없고, 각 쓰레드는 block 되지 않습니다.
구현을 정확히는 모르겠지만, addnull님이 말씀하신 implicit lock도 필요없을 것 같습니다. volatile 변수만 가지고도 구현 가능할 것 같습니다.
write 쓰레드가 한 개 이상이라면 write 작업 중에는 block 될 수 있습니다.
문제는 write가 자주 일어날 경우에 비용이 크다는 점이지요.
write가 자주 일어나지 않고, non-blocking 행동이 필요하다면 고려할만한 해결책입니다.

cleol의 이미지

음.. 왜 "수정" 버튼이 안 보이지요? 뭐 여하튼,

> thread-safe가 보장 안 되면, 쓰는 작업이 5byte 중에 2~3byte만 완료된 상황에서도 다른 쓰레드의 읽기 작업이 실행될 수 있습니다.

단순히 이를 위해서라면 자바 메모리 모델에서는 volatile 변수에 대한 write 면 충분합니다.
굳이 synchronize 를 사용해서 lock을 할 필요는 없습니다.
CopyOnWriteArrayList 도 이를 이용해서 구현된 것이구요.

addnull의 이미지

volatile 변수가 있었군요. 하나 배워갑니다 ㅎㅎ

volatile 변수에 대해서 좀 더 찾아봤습니다.
질문자께서 원하시는 mutlithread 환경에서 atomic get and set operation의 정상 동작을 보장하려면 자바 버전 5 이상을 사용하셔야합니다.

volatile 변수 원 의미(C와 C++에서)는 메모리에 직접 데이터를 쓰고 읽겠다는 뜻이고,
자바 5 이후부터는 이 의미를 확장해서 atomic operation들의 happens-before relationship이 된다고 합니다.

volatile 변수를 사용하지 말아야할 때는 복합 연산(complex operation)할 때라고 합니다.
http://www.javamex.com/tutorials/synchronization_volatile_dangers.shtml

이런 경우엔 lock을 사용하지 않고선 synchronize 문제를 피해갈 수 없겠죠 :)

kgcrom의 이미지

http://www.java2s.com/Code/Java/Threads/Producer-Consumer.htm

원하시는 답은 아니지만
Producer-Consumer 패턴 사용하시면 좋을것같은데요?

흘러가고있는 지금 이 시간에 충실하자.

purple의 이미지

lock이 걸리면 안된다는 게 무슨 의도로 하신 말씀인지 모르겠습니다만, 적절한 동기화 작업(synchronized)없이 서로 다른 쓰레드가 자료를 공유하게 할 순 없습니다. 이에 관해서는 java concurrency 에 관련된 문서를 보시면 될 꺼구요.

그냥 두 스레드가 producer - consumer 구조로 작동하는 걸 구현하려는 것이면 java.util.concurrent.BlockingQueue 인터페이스를 구현한 것들을 사용하시는 게 좋아보이네요.

jick의 이미지

Java는 잘 모릅니다만, 찾아보니까 이런 게 있네요. 혹시 원하시는 게 이런거?

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.