Multithreading (inactivity classes)

Sorry for the long code post, but I'm wondering if anyone can help with the multithreading issue (I'm completely new to multithreading). I am trying to create a facade class for the RESTFUL web services API that can be used by multiple threads. I use HttpURLConnection to connect and Google GSON to convert JSON data to and from.

The next class is what I still have. In this example, it has one public method for calling the API (authenticateCustomer ()), and private methods are used to facilitate calling the API (for example, to build a POST data string, create a POST request, etc.).

I am making one instance of this class and sharing it with 1000 threads. Streams use the authenticateCustomer () method. Most threads work, but there are some threads that get a null pointer exception because I did not perform any synchronization. If I make the authenticateCustomer () method "synchronized", it will work. The problem is that this leads to bad concurrency (say, for example, a POST request suddenly takes a lot of time, it delays all other threads).

Now to my question. Is the class below not stateless and therefore thread safe? Very few fields that are in a class are declared final and assigned in the constructor. All methods use local variables. The Gson object is stateless (according to their website) and is in any case created as a local variable in the API method.

public final class QuizSyncAPIFacade 
{
    // API Connection Details
private final String m_apiDomain;
private final String m_apiContentType;
private final int m_bufferSize;

// Constructors
public QuizSyncAPIFacade()
{
    m_apiDomain      = "http://*****************************";
    m_apiContentType = ".json";
    m_bufferSize = 8192; // 8k
}

private String readInputStream(InputStream stream) throws IOException
{
        // Create a buffer for the input stream
    byte[] buffer = new byte[m_bufferSize];

    int readCount;

    StringBuilder builder = new StringBuilder();

    while ((readCount = stream.read(buffer)) > -1) {
        builder.append(new String(buffer, 0, readCount));
    }

    return builder.toString();
}

private String buildPostData(HashMap<String,String> postData) throws UnsupportedEncodingException
{
    String data = "";

    for (Map.Entry<String,String> entry : postData.entrySet()) 
    {
        data += (URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&");        
    }

    // Trim the last character (a trailing ampersand)
    int length = data.length();

    if (length > 0) {
        data = data.substring(0, (length - 1));
    }

    return data;
}

private String buildJSONError(String message, String name, String at)
{
    String error = "{\"errors\":[{\"message\":\"" + message + "\",\"name\":\"" + name + "\",\"at\":\"" + at + "\"}]}";

    return error;
}

private String callPost(String url, HashMap<String,String> postData) throws IOException
{
    // Set up the URL for the API call 
    URL apiUrl = new URL(url);

    // Build the post data
    String data = buildPostData(postData);

    // Call the API action
    HttpURLConnection conn;

    try {
        conn = (HttpURLConnection)apiUrl.openConnection();
    } catch (IOException e) {
        throw new IOException(buildJSONError("Failed to open a connection.", "CONNECTION_FAILURE", ""));
    }

    // Set connection parameters for posting data
    conn.setRequestMethod("POST");
    conn.setUseCaches(false);
    conn.setDoInput(true);
    conn.setDoOutput(true);

    // Write post data
    try {
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(data);
        wr.flush();
        wr.close();
    } catch (IOException e) {
        throw new IOException(buildJSONError("Failed to post data in output stream (Connection OK?).", "POST_DATA_FAILURE", ""));           
    }

    // Read the response from the server                
    InputStream is;

    try {
        is = conn.getInputStream();
    } catch (IOException e) {
        InputStream errStr = conn.getErrorStream();

        if (errStr != null) 
        {
            String errResponse = readInputStream(errStr);
            throw new IOException(errResponse);
        } 
        else 
        {
            throw new IOException(buildJSONError("Failed to read error stream (Connection OK?).", "ERROR_STREAM_FAILURE", ""));
        }
    }

    // Read and return response from the server
    return readInputStream(is);
}

/* -------------------------------------
 * 
 * Synchronous API calls
 * 
   ------------------------------------- */

public APIResponse<CustomerAuthentication> authenticateCustomer(HashMap<String,String> postData)
{
    // Set the URL for this API call
    String apiURL = m_apiDomain + "/customer/authenticate" + m_apiContentType;

    Gson jsonConv = new Gson();

    String apiResponse = "";

    try 
    { 
        // Call the API action
        apiResponse = callPost(apiURL, postData);

        // Convert JSON response to the required object type
        CustomerAuthentication customerAuth = jsonConv.fromJson(apiResponse, CustomerAuthentication.class);

        // Build and return the API response object
        APIResponse<CustomerAuthentication> result = new APIResponse<CustomerAuthentication>(true, customerAuth, null);

        return result;
    } 
    catch (IOException e) 
    {
        // Build and return the API response object for a failure with error list
        APIErrorList errorList = jsonConv.fromJson(e.getMessage(), APIErrorList.class);

        APIResponse<CustomerAuthentication> result = new APIResponse<CustomerAuthentication>(false, null, errorList);

        return result;
    }
}

}

+3
source share
2 answers

If you receive an error message, it may be due to the fact that you are overloading the authentication service (something does not happen if you do it at a time). Perhaps it returns an error, such as 500, 503 or 504, ignoring and not expecting anything, you return null http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

, , 1000 , , , .

, , null.

20 , Semaphore . .

+2

, , , , , .

0

All Articles