2015-01-29 4 views
2

10 개의 스레드 그룹을 시작하고 싶습니다. 내 주요 프로그램 생성자에서 내가 사용 :ExecutorService에 대한 오해 -

executor = Executors.newFixedThreadPool(NTHREADS); 

Callable<String> poller; 
for (int i = 0; i < NTHREADS; ++i) { 
    Future<String> future = executor.submit(new Poller(0x3A, m_socket, ds_in, ds_out, socketLock)); 
    set.add(future); 
} 

을 클래스 폴러의() 메서드 호출을 위해 내가 가진 :

public String call() 
{ 
    // This has to be set here, otherwise all threads will have a name of "main". 
    myID = Thread.currentThread().getName(); 

    boolean shutup_loop = true; 
    do { 
     System.out.println("Hey, I'm thread " + myID); 
     System.out.println("Hey, I'm thread " + Thread.currentThread().getName()); 
     try { 
      Thread.sleep(10); 
     } 
     catch (java.lang.InterruptedException e) { 
      System.out.println("thread " + myID + ": " + e); 
     } 

     // Do if you want the printing to all match up on one line 
     synchronized (this) { 
      ByteArrayOutputStream baos = SendReceive(pollPacket); 

      System.out.print(myID + ": "); 
      if (baos != null) { 
       printStuff(baos); 
       System.out.println(); 
      } 
      notify(); 
     } 

    } while (shutup_loop); 

    return "poller is finished"; 
} 

이 폴러 스레드 SendReceive(), 폴러 클래스의 일부를 요구하고있다 :

public synchronized ByteArrayOutputStream SendReceive(byte[] toSend) 
{ 
    System.out.println("START"); 
    System.out.println("SendReceive()1 " + myID); 
    System.out.println("SendReceive()2 " + Thread.currentThread().getName()); 
    System.out.println("END"); 

    try { 
     ds_out.write(toSend, 0, toSend.length); 
     ds_out.flush(); 
    } 
    catch (java.io.IOException e) { 
     System.out.println("thread " + myID + ": " + e); 
    } 

    try { 
     m_socket.setSoTimeout(200);  // <-- might need tweaking 
    } 
    catch (java.net.SocketException e) { 
     System.out.println("thread " + myID + ": " + e); 
    } 

    ByteArrayOutputStream baos = null; 
    try { 
     baos = getResponse(ds_in); 
    } 
    catch (java.io.IOException e) { 
     System.out.println("thread " + myID + ": " + e); 
    } 

    return baos; 
} 

이 내가 출력이 닮은 기대 동기화 방법이기 때문에 :

가 403,210

대신이하고있다 : 무엇이 제공

START 
START 
START 
START 
START 
START 
SendReceive()1 pool-1-thread-2 
START 
START 
START 
SendReceive()1 pool-1-thread-6 
SendReceive()1 pool-1-thread-7 
SendReceive()2 pool-1-thread-2 
SendReceive()1 pool-1-thread-3 
SendReceive()2 pool-1-thread-6 
SendReceive()1 pool-1-thread-1 
SendReceive()1 pool-1-thread-9 
SendReceive()1 pool-1-thread-8 
SendReceive()2 pool-1-thread-9 
END 
... 

를?

+0

귀하의 질문은'Exec'에 관한 것이지,'ExecutorService'에 관한 것이 아닙니다. – immibis

+0

당신의 질문은'Exec'에 관한 것이지'ExecutorService'에 관한 것이 아닙니다. – immibis

+0

'SendReceive' 선언에서'synchronized'을 제거합니다 (어쨌든 아무것도하지 않습니다). 'Send (동기화) (Poller.class)'로'SendReceive'를 호출 할 때'synchronized (this)'를 변경하십시오. 그러면 의도 한대로 작동합니다. 이유를 이해하는 데 필요한 assillias의 답변을 참조하십시오. – Dima

답변

2

synchronized은 자물쇠로 사용합니다. 귀하의 경우에는 각각 여러 개의 자물쇠가 사용되는 Poller 개의 인스턴스가 있습니다. 당신이 공통의 잠금을 필요로 작동하게하려면

  • 하나가 방법 static
  • 을 사용하거나 공통 private static final Object lock = new Object();을 사용할 synchronized(lock) {...}
0

만약 당신이 후 폴러 사이의 소켓을 공유하고있는 것을, 실행 프로그램 서비스를 사용할 필요가 없습니다. 어쨌든 소켓 사용을 직렬화해야하므로 폴링 작업 목록을 반복하고 현재 소켓을 사용하여 작업 할 수 있습니다.

반면에 동일한 소켓을 사용하여 병렬로 폴링하려는 경우 네트워크 프로토콜은 응답을 기다리지 않고 폴 메시지를 보낼 수 있도록 지원해야합니다. 비행 중에 여러 번 요청할 것입니다. 그러나 나는 그것이 당신이 해결하려고하는 것보다 더 크고 다른 문제라고 생각합니다.

+0

사실,하지만 동기화 및 리소스 잠금 연습을 위해이 작업을 수행하고있었습니다. –