4
\$\begingroup\$

From OOP & OOD point of view, is it good idea to define Java-threads inside of the static method or in this case it's better to use instance-based method?

public class ThreadPool {

    public static void stringAnalysis(ArrayList<String> strData) {
        Thread t;
        t = new Thread(new SentimentAnalysis(strData));
        t.start();
    }
}

public class SentimentAnalysis implements Runnable {

    private ArrayList<String> strData;

    public SentimentAnalysis(ArrayList<String> strData) {
        this.strData = strData;
    }

    public void computeSentiment(ArrayList<String> strData) {
        StanfordNLP_forked.analyze(strData);
    }

    public void run() {
        this.computeSentiment(strData);
    }
}

StanfordNLP_forked is a forked version of StanfordCoreNLP for educational purpose only. StanfordNLP_forked.analyze(strData) performs text analysis of the strings array and replace each string with sentimental rank value. For the moment, I just check in the debugger the result of the analysis, later I'll add some functionality.

\$\endgroup\$
2
\$\begingroup\$

The Best-practice threading policy in Java is now to use the ExecutorService implementations found in the java.util.concurrent package.

Before we go there, though, your current code should be improved. The method:

public static void stringAnalysis(ArrayList<String> strData) {
    Thread t;
    t = new Thread(new SentimentAnalysis(strData));
    t.start();
}

creates and starts a thread. The thread that is started is a regular thread, as opposed to a daemon thread. The JVM will exit when all threads complete, or all the remaining threads are Daemon (background) threads: see Thread.setDaemon(boolean).

You should typically use Daemon threads (and I believe that Java has a bug in that Daemon threads should be the default).

Additionally, there is no reason to 'Declare' the t Thread variable before assigning to it.

Finally, for many reasons, it is nice to give threads names.

I would have the code:

public static void stringAnalysis(ArrayList<String> strData) {
    Thread toRun = new Thread(new SentimentAnalysis(strData), "Sentiment Analysis thread");
    toRun.setDaemon(true);
    toRun.start();
}

But, in reality, I would use an Executor service....

Executors.

Executor services work best with Daemon threads too. Here's a method that creates a Daemon thread for an Executor service:

private static final AtomicInteger sentimentThreadID = new AtomicInteger();

public static Thread createSentimentThread(Runnable toRun) {
    String name = "Sentiment Thread " + sentimentThreadID.incrementAndGet();
    Thread myThread = new Thread(toRun, name);
    myThread.setDaemon(true);
    return myThread();
}

Executors have their own Runnable that they use to create the thread. When you have your runnable, you pass it to the Executor, and the Executor runs it on one of the Executor's threads.

So, you can create an ExecutorService with something like (using Java 8):

ExecutorService sentimentService = Executors.newCachedThreadPool(
        runnable -> createSentimentThread(runnable)
    );

Java 7 would be slightly longer with:

ThreadFactory factory = new ThreadFactory() {
   @Override
   public Thread newThread(Runnable r) {
     return createSentimentThread(r);
   }

};
ExecutorService sentimentService = Executors.newCachedThreadPool(factory);

Once you have the sentimentService, you can run your analysis Runnables with:

sentimentService.submit(new SentimentAnalysis(strData));
\$\endgroup\$
1
\$\begingroup\$

Although I don't know what

this.analyze(strData)

does, and someone correct me if I am missing it:

You can just do:

strData.parallelStream().forEach(s -> StanfordNLP_forked.analyze(strData))

or, if it has some sort of result value result (you do want the analysis, right?) you could use reduce (if you can combine the result) or implement a collector if you want them in a list or something

I am feeling too lazy to whip one up for your case right now, but look here

The whole point os j8 stream is to make parallelization trivial through the use of functional expression.

Admittedly, I am working on understanding j8 myself.

\$\endgroup\$
  • \$\begingroup\$ this.analyze(strData) replaced with this.computeSentiment(strData) Thanks for the link, I'll check it. \$\endgroup\$ – Mike B. Dec 6 '14 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.