2012-08-29 2 views
1

나는 목록이있는 클래스를 작성 중입니다. 그리고 실행 방법 Runnable에서 목록을 인스턴스화합니다. 다음과 같이 :스레드의 목록의 메모리 범위

public void sendEmailToLegalUsers() { 
    Log.info("JYM===================================="); 

    try { 
     new Runnable() { 

      public void run() { 
       userCns = new ArrayList<String>(); 
       recipients = new ArrayList<String>(); 

       ///other codes 
      } 
     };     
    } catch (Exception e) { 
     Log.info("Error occurred in LDAPSendMail: "+ e.getMessage()); 
    } 

    Log.info("END===================================="); 
} 

이제 sendEmailToLegalUsers 메서드가 호출 될 때마다 새 스레드가 생성됩니다. 이제 목록의 메모리 범위가 클래스 수준에 한정되어 있는지 궁금합니다. 클래스 수준에 바인딩되어 있고이 메서드가 두 번 호출되는 경우 스레드 1이 만든 목록의 어떤 일이 발생하는지도 궁금합니다. 스레드 2) 또는 스레드가 자신의 범위에서 실행될 때 목록은 각 스레드에 대해 다른 범위를 갖게됩니다. 두 개 또는 여러 개의 스레드간에 목록 데이터가 혼합 될 가능성이 있습니까?

답변

4

두 스레드 모두에 동일한 Runnable 클래스를 사용하고있는 경우에는 겹칩니다. 각 스레드에 대해 별도의 new Runnable()을 가지고 있다면, 아니오, 별도의 목록 인스턴스가됩니다. 그러나 이것은 목록이 Runnable에 로컬로 정의 된 경우에만 해당됩니다. 호출 클래스에 목록이 정의되어 있고 두 번째로 메서드를 호출하면 userCnsrecipients 필드를 덮어 씁니다.

귀하의 경우에는 어떤 스레드도 전혀 포크되지 않습니다. 내가 보는 것은 Runnable을 인스턴스화하는 것입니다. 당신은 당신이 같은 일을하려고하지 않는 확신이 경우

new Thread(new Runnable() { 
     public void run() { 
      // lists are local to the runnable 
      List<String> userCns = new ArrayList<String>(); 
      List<String> recipients = new ArrayList<String>(); 
      ///other codes 
     } 
    }).start(); 

을, 당신이 당신의 sendEmailToLegalUsers() 메서드를 호출 할 때마다, 새로운 Runnable는 새 목록으로 작성됩니다.

+0

설명 주셔서 대단히 감사합니다. –

0

동일한 스레드가 여러 스레드 인 경우 run()인데 목록이 인스턴스 범위이고 두 스레드가 같은 목록에서 작동하기 때문에 잘못된 결과가 발생할 수 있습니다.

각 스레드에 대해 새로운 Runnable()을 작성하면 해당 스레드는 자체 사본을 가지며 서로 다른 데이터를 갱신하지 않습니다.

4

각 스레드에 대해 새로운 목록 쌍을 만듭니다. 또한 로컬 변수를 만들어야합니다. 그렇지 않으면 목록에 있지만 목록에 대한 참조가 아닌 스레드 안전성 문제가 발생할 수 있습니다.

new Thread(new Runnable() { 
    public void run() { 
     List<String> userCns = new ArrayList<String>(); 
     List<String> recipients = new ArrayList<String>(); 

     ///other codes 
    } 
}).start(); 

userCns 또는 수신자가 필드 인 경우 필드가 공유되어 있기 때문에 스레드간에 공유 할 수 있습니다.

0

당신은 새로운 Runnable을 만들고 있지만 아무것도하지 않습니다. 확실히 새로운 Thread를 생성하지는 않을 것입니다.

그러나 생성 된 Runnables를 스레드에 전달하면 참조가 Runnable 인스턴스로 제한됩니다.

관련 문제