2014-02-28 2 views
2

MyService 클래스의 execute 메소드를 호출하는 Client 클래스가 있습니다. 이 메서드는 차례로 InsertDAO 클래스를 호출합니다. 이 InsertDAO에는 인스턴스 변수가있는 상태가 있습니다. 이것은 MyService 클래스의 execute 메소드에서만 호출됩니다. 하나는 직접 InsertDAO 클래스를 호출 할 수 없습니다.여러 스레드가 InsertDAO에 입력 할 수 있습니까?

스레드를 만들지는 않지만 응용 프로그램 서버는 클라이언트 클래스에서 스레드를 만들 수 있습니다. 자, 이것이 InsertDAO 클래스에 어떤 영향을 미치는지 이해하고 싶습니다.

  1. 여러 스레드가 동시에 InsertDAO의 개체에 액세스 할 수 있습니까? - yes/no
  2. 스레드가 Client 클래스에서 생성되면 MyService 클래스의 동일한 인스턴스가 Client의 모든 스레드에 제공됩니다. 그런 다음 모든 스레드는 MyService의 "execute"메소드를 호출해야합니다. 이것은 모든 스레드가 자신의 InsertDAO 인스턴스를 가지고 있음을 의미합니다 (MyService 클래스의 execute 메소드 내에 InsertDAO 객체를 생성 중입니다). 그렇다면 여러 스레드가 동시에 InsertDAO에 들어갈 수 없습니다. 내 이해가 맞습니까?
  3. 여러 스레드가 MyService.execute()에 어떻게 입력 할 수 있습니까?
  4. 어떻게 여러 스레드가 InsertDAO 클래스에 입력 할 수 있습니까? - 이것이 사실이라면 약간의 설명.
  5. 어떻게 성능에 영향을 미치지 않고 threadsafe를 만들 수 있습니까?

전문가에게이 점에 대해 의견을 나누십시오. 아래는 제 코드입니다.

//code starts here 
public class Client{ 
    public void performExecution(){ 
     InvoiceVO createInvoiceVO = new InvoiceVO(); 
     MyService service = mew MyService(); 
      createInvoiceVO = service.execute(createInvoiceVO); 
     //retrieve successful/failure information from createInvoiceVO 
    } 
} 

public class MyService{ 
    public InvoiceVO execute(InvoiceVO createInvoiceVO){ 
     InsertDAO insertDAO = new InsertDAO(); 
      insertDAO.process(createInvoiceVO); 
    } 
} 

public class InsertDAO{ 
    private List<LineItem> lineItemsList = new ArrayList<LineItem>(); 
    private List<TaxVO> taxVOList = new ArrayList<TaxVO>(); 
    private Connection connection = null; 

    public InvoiceVO process(InvoiceVO createInvoiceVO){ 
     this.lineItemsList = createInvoiceVO.getLineItemsList(); 
     this.taxVOList = createInvoiceVO.getTaxVOList(); 

     connection = getConnection(); 
     //insert tax vo objects 
     insertTaxVOObjects(taxVOList); 

     //insert line items 
     insertLineItems(this.lineItemsList); 

     //commit operation 

     //close connection 
     closeConnection(); 
    } 

    private void insertTaxVOObjects(List<TaxVO> taxVOList){ 
     //code to insert TaxVO objects 
    } 

    private void insertLineItems(List<LineItem> lineItemsList){ 
     //code to insert LineItem objects 
    } 

    private void getConnection(){ 
     //code to return connection 
    } 

    private void closeConnection(){ 
     //code to close connection 
    } 
} 
+0

개체를 참조하도록 편집했습니다. – Gana

답변

2

올바른 질문을하지 않고 스레드가 클래스를 입력하지 않고 개체를 입력합니다. 우리는 객체의 생명주기와 스레드가 만들어 질 때를 봐야합니다.

이제는 실행 환경을 이해하지 못합니다. 스레드가 만들어지는 위치가 명확하지 않지만 Client Objects가 만들어지고 각 개체의 performExecution() 메서드가 자체 스레드에서 실행될 수 있다고 가정합니다 . 문제는 이제 두 개의 스레드에서 동시에 두 개의 InsertDAO 개체에 액세스 할 수 있는지 또는 두 개의 InsertDAO 개체가 일부 데이터를 공유 할 수 있는지 여부와 두 개의 스레드가 간섭 할 수 있는지 여부입니다.

먼저 각 InsertDAO 개체는 개별적이며 변수가 있지만 변수는 정적이 아닙니다. 당신은 그래서 데이터가 하나의 객체 인스턴스가 소유

this.lineItemsList 

예를

를 들어, (아마도 다른 스레드에서) 다른 객체가 에 첨부 된 데이터를 볼 수 있습니다. 참고 정적 데이터가있는 경우 모든 인스턴스에서 볼 수 있으므로 문제가 발생합니다. 첫 번째 규칙 : 동기화 된 액세스로 보호하지 않는 한 고정 데이터가 아닙니다.

잠재적 인 문제가있는 곳 중 하나는 연결을 요청하는 것입니다. 이제 연결은 일반적으로 풀링됩니다. 우리는 실제로 모든 요청에 ​​대해 연결을 열지 않으려합니다. 대신 풀에서 하나를 가져 와서 사용했을 때 돌아옵니다. 전체 아이디어는 스레드가 동일한 풀을 공유한다는 것입니다. 따라서 일반적인 원칙은 삽입 변수 오브젝트가 멤버 변수로 가지고 있지 않은 것을 사용하는 어떤 것이라도 thread-safe이어야합니다. 즉, 작성자는이 스레드에 액세스하는 여러 스레드를 예상하여 작성해야합니다. 공유 풀 : 작성자는 일종의 동기화 액세스를 사용해야합니다. 규칙 2 : 자신의 코드뿐만 아니라 사용하는 것을 살펴보십시오.

마지막 비트, 두 개의 스레드가 하나의 InsertDAO 개체를 공유 할 수 있습니까? 당신이 그들을 만드는 방법에 표정에 대답하기 :

public InvoiceVO execute(InvoiceVO createInvoiceVO){ 
    InsertDAO insertDAO = new InsertDAO(); 
     insertDAO.process(createInvoiceVO); 
} 

다음은 객체를 생성, 그것은 방법 및 반환 (암시 적으로 개체를 해제)의 호출이 볼 수있는 다른 스레드, 그것은 당신의 스택에 지역 없습니다. 따라서 하나의 스레드 만 하나의 InsertDAO 객체를 사용한다는 것을 알 수 있습니다. 규칙 3 : 개체를 볼 수있는 스레드 수를 결정하는 것은 호출자입니다. 귀하의 경우에는 하나의 스레드를 확보했습니다.

+0

좋습니다. 여러 스레드가 한 번에 InsertDAO 개체에 액세스 할 수 있는지 여부에 대한 나의 의심을 날려 버렸습니다. 외부에서 멀티 스레드가 가능한 연결 풀에 대한 언급은 나에게 부딪치지 않는 좋은 지적입니다. 따라서 "게이트"(MyService.execute())를 만들고 멤버 변수 만 있으면 (InsertDAO와 같이) 비 정적 상태 저장 객체는 여러 스레드에서 보호됩니다. 그걸 알면 아주 좋습니다. 건배. 귀하의 설명을 주셔서 감사합니다 – Gana

+0

좋은 설명. – Rembo

관련 문제