멀티스레드 환경에서 이뮤터블 패턴이 장점을 가짐. 즉 스레드간 특정 자원을 공유하는
문제에 대해 방지가 가능. 물론 concurrent패키지 계열의 클래스들을 사용해도 될테지만..
그래서 string이 이뮤터블이 된듯(물론 풀링도 가능하고).. 흐음.. 원본을 두고 사본을 건낸다..
어제 ejb패턴에서도 봤듯.. 서버측에서 데이터에 대해 클라가 요청시 사본을 생성해서 보내주
는 의미를 고민해볼것


lock관련

http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html



동기화 관련

생산자,소비자 패턴


생뚱맞지만.. 예전에 bean xmlencoder xmldecoder .. 스윙 컴포넌트(bean베이스)의 정보를 xml로..


글고 property change 서포터..


오픈소스 관련


************************************************************************************

생뚱2.. 스윙 유틸의 메서드중.. addnotify..  awt.frame -> awt.window -> awt.container -> awt.component까지.. 환장함..

Makes this Component displayable by connecting it to a native screen resource. This method is called internally by 

the toolkit and should not be called directly by programs.
This method changes layout-related information, and therefore, invalidates the component hierarchy.

Since:
JDK1.0

See also:
isDisplayable()
removeNotify()
invalidate()


6855 
6856     public void More ...addNotify() {
6857         synchronized (getTreeLock()) {
6858             ComponentPeer peer = this.peer;
6859             if (peer == null || peer instanceof LightweightPeer){
6860                 if (peer == null) {
6861                     // Update both the Component's peer variable and the local
6862                     // variable we use for thread safety.
6863                     this.peer = peer = getToolkit().createComponent(this);
6864                 }
6865 
6866                 // This is a lightweight component which means it won't be
6867                 // able to get window-related events by itself.  If any
6868                 // have been enabled, then the nearest native container must
6869                 // be enabled.
6870                 if (parent != null) {
6871                     long mask = 0;
6872                     if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
6873                         mask |= AWTEvent.MOUSE_EVENT_MASK;
6874                     }
6875                     if ((mouseMotionListener != null) ||
6876                         ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
6877                         mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
6878                     }
6879                     if ((mouseWheelListener != null ) ||
6880                         ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
6881                         mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
6882                     }
6883                     if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
6884                         mask |= AWTEvent.FOCUS_EVENT_MASK;
6885                     }
6886                     if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
6887                         mask |= AWTEvent.KEY_EVENT_MASK;
6888                     }
6889                     if (mask != 0) {
6890                         parent.proxyEnableEvents(mask);
6891                     }
6892                 }
6893             } else {
6894                 // It's native. If the parent is lightweight it will need some
6895                 // help.
6896                 Container parent = getContainer();
6897                 if (parent != null && parent.isLightweight()) {
6898                     relocateComponent();
6899                     if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
6900                     {
6901                         peer.setVisible(false);
6902                     }
6903                 }
6904             }
6905             invalidate();
6906 
6907             int npopups = (popups != null? popups.size() : 0);
6908             for (int i = 0 ; i < npopups ; i++) {
6909                 PopupMenu popup = (PopupMenu)popups.elementAt(i);
6910                 popup.addNotify();
6911             }
6912 
6913             if (dropTarget != null) dropTarget.addNotify(peer);
6914 
6915             peerFont = getFont();
6916 
6917             if (getContainer() != null && !isAddNotifyComplete) {
6918                 getContainer().increaseComponentCount(this);
6919             }
6920 
6921 
6922             // Update stacking order
6923             updateZOrder();
6924 
6925             if (!isAddNotifyComplete) {
6926                 mixOnShowing();
6927             }
6928 
6929             isAddNotifyComplete = true;
6930 
6931             if (hierarchyListener != null ||
6932                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
6933                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6934                 HierarchyEvent e =
6935                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
6936                                        this, parent,
6937                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
6938                                        ((isRecursivelyVisible())
6939                                         ? HierarchyEvent.SHOWING_CHANGED
6940                                         : 0));
6941                 dispatchEvent(e);
6942             }
6943         }
6944     }



by givingsheart 2014. 1. 2. 09:40

http://www.okjsp.net/seq/237333



추가로 java.util.observer 인터페이스, 
java.lang.object 의 notify() 메서드,


Runaable Obj A---------------------------->
                     event X
                              Runaable Obj B------------------------->
                                          event Y
                                                    Runaable Obj C------------------->


를 객체 지향적으로 처리하고 싶기 때문이다.

아직 개념이 부족해.. 컨셉 자체도 명확하지 않다. 단지 내 객체들간에 이벤트 드라이븐 
방식의 처리를 위해 옵저버 인터페이스를 이해할 필요가 있었고, 또한 Object 클래스에
정의된 notify() 에 대한 이해가 거의 없기 때문이다.


난 아래 링크의 글을 정확히 이해할수없다


(추가)
이벤트를 기반으로 한 비동기 프로그래밍 문제이다. 자바스크립트의 핵심 개념이 된다.
비동기 처리할 부분(비동기 함수 사용) VS 순차적 제약이 필요한 부분(해당 함수 내에서 아..
..어찌 해결하는지 까먹음.. ) 





by givingsheart 2014. 1. 2. 09:03

결론:thread safe가 필요할 경우 아래의 패키지를 활용할 것! 

 멀티스레드 동기화 문제에 대한 자바측의 편의 제공 클래스! java.util.concurrent 패키지!

=>한마디로 데이터를 원자적으로 보호한다. (내부적으로 synchrozied 처럼 lock, unlock 래핑한 것인듯.. 
   참조를 보호하는 거야.. reflect가 있으니.. Class 를 Object로 처리 가능할테고.. 아님 말고 -_-;)


패키지 java.util.concurrent.atomic

단일의 변수에 대한 락 프리로 thread 세이프인 프로그래밍을 지원하는 클래스의 소규모의 툴 킷입니다.


************************기타 찌끄레기 방법? 심플하니 좋은건가?********************


멀티쓰레드 환경에서 클래스의 멤버변수를 안전하게 사용하기 위해서 사용하는 방법이 sychronized 블록을 사용하거나, 변수를 volatile로 선언하는 방식이 있습니다. 두 방식의 차이에 대해 알아보았습니다.

 

Question of the month: Volatile vs. Synchronized re-visited

 

먼저 각각의 방식에 대한 한 쓰레드에서 처리 방식을 살펴보면 다음과 같습니다.

 

volatile

synchronized

Get a global lock on the variableGet a global lock on the monitor
Update the one variable from main memoryUpdate all shared variables that have been accessed from main memory
Process some statements
Write any change of the one variable back to main memoryWrite all shared variables that have been changed back to main memory
Release the lockRelease the lock

 

여기에서 알 수 있듯이 volatile이 선언되지 않은 멤버변수는 sychronized 블록이 아닌 곳에서 사용할 경우, 쓰레드가 변수값들을 복사해서 사용하기 때문에 다른 쓰레드에서 값을 변경했을 경우 같은 변수임에도 불구하고 실제와 다른 값을 읽을 수 있다는 것입니다.

 

Use Synchronized or Volatile when Accessing Shared Variables

 

각각의 방식의 장단점을 살펴보면 다음과 같습니다.

 

TechniqueAdvantagesDisadvantages

synchronized

Private working memory is reconciled with main memory when the lock is obtained and when the lock is released.Eliminates concurrency.

volatile

Allows concurrency.Private working memory is reconciled with main memory on each variable access.


by givingsheart 2014. 1. 1. 16:33
package threadFight;

public class main
{
public static void main(String[] args)
{
// TODO Auto-generated method stub
Unit unit1 = new Unit();
Thread th = new Thread(unit1);
th.start();
}
}

class Unit implements Runnable
{
public String name = "홍길동";
public int hp = 50;
@Override
public void run()
{
while(this.isLive())
{
// TODO Auto-generated method stub
//랜덤으로 상대에게 타격한다.
int at = (int)(Math.random()*6 ); //0~5
hp-=at;
System.out.println(name + " 님이 " + at + " 데미지로 자해하고 있습니다. hp:" + hp);
}
System.out.println(name + " 님이 뒤졌습니다.");
}
public boolean isLive()
{
return hp >0;
}
}


아..글고,.. 런에이블 편하게 쓸라면...흠.. 멤버 필드로 Thread를 갖고.. 위임 패턴을 적용해볼까?  

class A 라면.. 런에이블 조립해서 run 재정의 하고.. 내부적으로 생성자에서 멤버 필드 스레드 객체를 생성할때.. this(자신)을 
매개변수로 넣으면 스레드는 이제 내 객체(a)를 참조할수 있으니.. start(){ thread.start(); } 처럼 간단하게 사용 가능할듯 .. 
=>문제는.. run()이 퍼블릭 인터페이스로 노출되는점 ㅠㅠ  사용자께서(나?) start()로 사용해 주시길..

public class ddd
{

public static void main(String[] args)
{
// TODO Auto-generated method stub
ChildA a = new ChildA();
ChildB b = new ChildB();
a.start();
b.start();

}

}

abstract class Base
{
protected Thread thread;
}

class ChildA extends Base implements Runnable
{
ChildA()
{
thread = new Thread(this);
}
@Override
public void run()
{
for(int i=0; i< 100; i++)
{
System.out.println(thread.getName());
}
}
public void start()
{
thread.start();
}
}

class ChildB extends Base implements Runnable
{
ChildB()
{
thread = new Thread(this);
}
@Override
public void run()
{
for(int i=0; i< 100; i++)
{
System.out.println(thread.getName());
}
}
public void start()
{
thread.start();
}
}


=>core api에서 제공하는 인터페이스의 사용에 대해 아주 쬐금 감을 잡은듯도 하다.. 상속을 받으면 유연하지 않으니.. 가급적
core api 의 경우 interface를 구현하고 해당 클래스를 멤버 필드로 갖자(상속보단 구성!)

아니면 말고.. 그만 놀고 공부하자  -_-;


ps.멀티 스레딩 관련 볼만한 책들.. 갖고 싶다..




by givingsheart 2014. 1. 1. 16:29
<불공평한 synchronized()>


동기화에 따른 스레드 굶어 죽기 문제를 아래의 클래스로 풀어낸다는 컨셉 (개요를 보니.. 제일 오래 대기한 스레드가 다음 우선권을 
얻는다는데..FIFO(선입선출) 방식)
=> 중요한건 아래의 ReentrantLock를 이용하면서 + try finally 블럭을 이용해 "반드시" unlock()처리를 해주는데 있는듯

=>위의 컨셉에서 약간의 문제점은 스레드 스케쥴링(우선순위priority)을 보장해주지 않는다는 것. 다음 페이지에선 우선순위에 따라
대기중인 스레드 리스트의 원소들을 정렬 해준다는 아이디어로 풀어내고 있음. 

=>이 아이디어를 java.awt의 이벤트 큐에 적용시켜 본다면? 즉 우선순위 이벤트라면 큐의 제일 앞으로 삽입... (이미 구현되어
있을까?)

java.util.concurrent.locks 
클래스 ReentrantLock


by givingsheart 2014. 1. 1. 16:07
| 1 |