Getting different results at different times when working in threads

@Path("/getVersion")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    public List getVersion(String getVersionJson) throws InterruptedException {
        List outputList = new ArrayList();
        try {
            JSONArray jsonArr = new JSONArray(getVersionJson);

            for (int j = 0; j < jsonArr.length(); j++) {
                JSONObject jsonObj = jsonArr.getJSONObject(j);
                String ip = jsonObj.getString("ipaddress");
                String username = jsonObj.getString("username");
                String password = jsonObj.getString("password");

                new Thread() {
                    public void run() {
                        //outputList.add(ip);
                        final String connectionStatus = getSSHConnection(ip, username, password);
                        // outputList.add(connectionStatus);
                        if (connectionStatus.equals("Connected")) {
                            // outputList.add(connectionStatus);
                            //Version Check
                            expect.send("bwshowver" + "\n");
                            if (expect.expect("$") > -1) {
                                String contt = "";
                                contt = (expect.before);
                                if (contt != null && contt != "") {

                                    contt = contt.replaceAll("\n+", "\n");
                                    contt = contt.replaceAll(" +", " ");

                                    String splitter[] = contt.split("\n");

                                    for (int i = 0; i < splitter.length; i++) {
                                        if (splitter[i].contains("Patches")) {
                                            final String patches = splitter[i];
                                        }
                                        //version
                                        if (splitter[i].contains("version")) {
                                            // final String version = splitter[i];
                                            outputList.add(splitter[i]);

                                        }

                                    }

                                } else {
                                    final String v1 = "Error in version check";
                                    System.out.println("Error in version check");
                                }
                            }
                        } else {
                            outputList.add(connectionStatus);
                        }
                    }
                }.start();
            }
        } catch (Exception e) {
            final String v = "Error";
            //     logger.error("Exception in getVersion Function-ServService Class: " + e.getMessage());
        } finally {
            stopSSH();
        }
        Thread.sleep(20000);
        //outputList.add("ffk");
        // outputList.add("f");
        return outputList;
    }

I created a method using Threads. In this method, I send jsonarray, which consists of json objects. I used to create this method without threads, and it worked correctly. Now, changing it to threads, I get different results at different times. Can you suggest me where I am wrong?

+4
source share
2 answers

There are three main things in the above code:

  • Use stream collections when changing them from multiple streams. If the collection does not explicitly indicate that it is thread safe, you must either capture the locks yourself or switch to a thread-safe collection.
  • Thread.sleep() , , . , . CountDownLatch , .
  • , , , . , runnable . , .

bare-bones, :

public List getVersion(String getVersionJson)
        throws InterruptedException, IOException {
    // You must use a thread-safe list.
    final List outputList = Collections.synchronizedList(new ArrayList());
    // This reference is used to keep track of exceptions thrown
    // in the runnable.
    final AtomicReference<Exception> exceptionReference =
        new AtomicReference(null);
    // This latch acts as a synchronization barrier so that all threads
    // must have put data into outputList before the code will go
    // past the latch.await() call
    final CountDownLatch latch = new CountDownLatch(jsonArr.length());
    for (int j = 0; j < jsonArr.length(); j++) {
        new Thread() {
            public void run() {
                try {   
                     // Do network I/O stuff
                     outputList.add(resultFromNetworkStuff);
                     latch.countDown();
                } catch (IOException e) {
                     // Set the exception for later retrieval
                     exceptionReference.compareAndSet(null, e);
                }
            }                        
        }.start();
    }

    // Wait for all the threads to finish before continuing.
    try {
        latch.await();
    } finally {
        // Even if we're interrupted, we want to close the connection.
        closeSSH();
    }
    if (exceptionRef.get() != null) {
        // Throw any exceptions we see in our threads.
        throw exceptionRef.get();
    }
    return outputList;
}
+2

. . .

20 , . , , . , , .

,

  • ( !)

  • .

, , , . , java- , . , , , . , ; , .

: catch ! . , .

: " " . , .

+1

Source: https://habr.com/ru/post/1673075/


All Articles