Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- erlang
- program
- Programming
- comic agile
- management
- Software Engineering
- hbase
- web
- ubuntu
- MySQL
- Spain
- leadership
- France
- Book
- Italy
- Python
- essay
- history
- Linux
- psychology
- Java
- Kuala Lumpur
- programming_book
- QT
- Malaysia
- agile
- RFID
- hadoop
- Book review
- django
Archives
- Today
- Total
volatile 관련 test 본문
class TestVolatile { public static void main(String[] args) { final int INTERVAL_TIME = 15; final BadAtomicLong bal = new BadAtomicLong(); final GoodAtomicLong gal = new GoodAtomicLong(); final GoodAtomicLong2 gal2 = new GoodAtomicLong2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { while ( true ) { Thread.sleep(INTERVAL_TIME); bal.getAndSet(1L); gal.getAndSet(1L); gal2.getAndSet(1L); } } catch (Exception e) {} } }); t1.start(); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { while ( true ) { Thread.sleep(INTERVAL_TIME); final long bVal = bal.getValue(); final long gVal = gal.getValue(); final long gVal2 = gal2.getValue(); if ( bVal != gVal || bVal != gVal2 || gVal != gVal2 ) System.out.println("t2: " + bVal + "\t" + gVal + "\t" + gVal2); } } catch (Exception e) {} } }); t2.start(); } } class BadAtomicLong { long value; synchronized void getAndSet(long d) { value += d; } long getValue() { return value; } } class GoodAtomicLong { volatile long value; void getAndSet(long d) { synchronized (this) { value += d; } } long getValue() { return value; } } class GoodAtomicLong2 { long value; synchronized void getAndSet(long d) { value += d; } synchronized long getValue() { return value; } } /* synchronized is re-entrant, meaning same thread can acquire an already held lock mulitple times synchronized: 해당 block 내의 것을 동기화 volatile: 읽기 전 system memory의 것으로 thread memory의 것을 변경함 위의 BadAtomicLong의 경우 t1에서 getAndSet()을 호출하고 t2에서 getValue()를 호출하면 t2의 값은 d가 더해진 것이 나오지 않는 경우가 있음 system memory의 값으로 thread memory의 값이 변경되지 않기 때문 그래서 GoodAtomicLong의 경우처럼 value를 volatile로 선언하면 t2에서 getValue()를 호출할 때마다 system memory의 값으로 갱신하므로 반영이 됨 getValue()를 synchronized로 선언을 해도 동작은 하겠지만 performance에서 손해 발생. 값을 쓰는 것이 아닌데도 동기화를 하므로 해당 시간동안 다른 thread의 접근이 금지되기 때문 $ java TestVolatile t2: 2062 2061 2061 */
Comments