0

I am using this code in a application for sending some string throw a socket.

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();

}

And from another thread I am calling this method

    private void send(String str) {

    OutgoingData.toSend = str;
}

Are there any problems that could appear using this implementation? Excepting the case when send() is called synchronously from two threads.

I am not using something like this:

   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();


}

Because the system on which this code is runned, has a limit on the number of threads a process can create and takes a long time to get a lock on an object.

4

2 に答える 2

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;
}

「遅い」かどうかに関係なく、何らかの形のスレッド同期が必要です。

于 2013-10-22T15:40:52.220 に答える
1

フィールドで忙しく待機するよりも良い選択は、 を使用するBlockingQueue<String>ことです。これにより、値を見逃すことがなく、何もすることがないときに CPU を消費することもありません。

キューとスレッド (プール) をまとめる良い方法は、両方を行う ExecutorService を使用することです。

あなたの場合、Socketストリームはすでにキューであるため、別のキューへの書き込みをキューに入れることは冗長である可能性が高く、出力ストリームをバッファリングするために本当に必要なものはすべてです。

このコードが実行されるシステムでは、プロセスが作成できるスレッドの数に制限があり、オブジェクトのロックを取得するのに長い時間がかかるためです。

スレッドを作成することは、スレッドを作成することの 100 倍以上です。理想的には、どちらも持ちたくありません。注: ソケットには既に書き込みロックがあります。

于 2013-10-22T16:02:01.470 に答える