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.

2 Answers 2

1

Your implementation is not thread safe:

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

You need some form of thread synchronization, regardless of whether or not it is "slow".

Sign up to request clarification or add additional context in comments.

2 Comments

+1 As the toSend field is not volatile, you might not ever see this field change.
You are right i haven't encountered this problem, but in theory, this is more than likely to happen
1

A better choice rather than busy waiting on a field is to use a BlockingQueue<String> This will ensure you never miss a value, nor do you consume CPU when there is nothing to do.

A good way of wrapping up a Queue and a Thread (pool) is to use an ExecutorService which does both.

In your case, a Socket stream is a queue already so queuing writing to another queue is likely to be redundant and all you really need to buffer your output stream.

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.

Creating a thread is more than 100x than creating a thread. Ideally you don't want to have either. Note: the Socket already has a write lock.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.