2013-10-22 4 views
0

일부 코드를 보내는 응용 프로그램에서이 코드를 사용하여 소켓을 던집니다. DataOutputStream 다른 접근 방식

public class OutgoingData { 

public static DataOutputStream dos = null; 
public static String toSend = ""; 
public static volatile boolean continuousSending = true; 
public static String toSendTemp = ""; 

public static void startSending(final DataOutputStream d) { 

    new Thread(new Runnable() { 

     public void run() { 
      try { 
       dos = d; 
       while (continuousSending) { 

        if (!toSend.equals(toSendTemp)) { 
         dos.writeUTF(toSend); 
         dos.flush(); 
         toSendTemp = toSend; 
        } 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    }).start(); 

} 

그리고 다른 스레드에서

나는이 구현을 사용하여 나타날 수있는 문제가이 방법

private void send(String str) { 

    OutgoingData.toSend = str; 
} 

를 호출 무엇입니까? send()가 두 스레드에서 동 기적으로 호출되는 경우를 제외하고. 이 코드는 runned되는 시스템이 잠금을 얻을하는 데 시간이 오래 프로세스가 만들 수있는 스레드의 수에 제한이 있고 걸리기 때문에

private void send(final String str){ 

    new Thread(new Runnable() { 

     @Override 
     public void run() { 
      synchronized (OutgoingData.dos) { 
       try { 
        OutgoingData.dos.writeUTF(str); 
        OutgoingData.dos.flush(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 
    }).start(); 


} 

:

나는 이런 식으로 뭔가를 사용하고 있지 않다 개체에.

답변

1

귀하의 구현은 스레드로부터 안전하지 않습니다 :

if (!toSend.equals(toSendTemp)) { 
    // toSend can be changed before this line happens 
    // causing you to miss data 
    dos.writeUTF(toSend); 
    dos.flush(); 

    // or here 
    toSendTemp = toSend; 
} 

당신은에 관계없이인지 여부의 "느린", 스레드 동기화의 형태가 필요합니다.

+0

+1 'toSend' 필드는 휘발성이 아니므로이 필드가 변경되지 않을 수도 있습니다. –

+0

당신은이 문제가 발생하지 않았지만 이론적으로는 이것이 일어날 가능성이 더 높습니다. – Titus

1

필드에서 통화 중 대기보다 더 나은 선택은 BlockingQueue<String>을 사용하는 것입니다. 이렇게하면 값을 놓치지 않고 아무 것도 할 필요가 없을 때 CPU를 소모하지 않습니다.

대기열과 스레드 (풀)를 묶는 좋은 방법은 두 가지를 모두 수행하는 ExecutorService를 사용하는 것입니다.

당신의 경우, 소켓 스트림은 이미 큐이므로 다른 큐에 대기열에 쓰기가 중복되어 출력 스트림을 버퍼해야합니다.

이 코드가 실행되는 시스템은 프로세스가 생성 할 수있는 스레드 수에 제한이 있으며 개체에 대한 잠금을 얻는 데 오랜 시간이 걸립니다.

스레드 만들기는 스레드를 만드는 것보다 100 배 이상입니다. 이상적으로 당신은 갖고 싶지 않습니다. 주 : Socket에는 이미 쓰기 잠금이 있습니다.