Java Multithreading – Transitioning from C++ Multithreading

designjavamultithreading

In C++, I've been accustomed to using threads in the following way:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex m;
int i = 0; 
void makeACallFromPhoneBooth() 
{
    m.lock();
      std::cout << i << " Hello Wife" << std::endl;
      i++;
    m.unlock();//man unlocks the phone booth door 
}

int main() 
{
    std::thread man1(makeACallFromPhoneBooth);
    std::thread man2(makeACallFromPhoneBooth);

    man1.join();
    man2.join();
    return 0;
}

But when I saw tutorials on Java multithreading, the entire class seems to be handling the thread's start and run states.

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;

   RunnableDemo( String name){
       threadName = name;
       System.out.println("Creating " +  threadName );
   }
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
     } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
     }
     System.out.println("Thread " +  threadName + " exiting.");
   }

   public void start ()
   {
      System.out.println("Starting " +  threadName );
      if (t == null)
      {
         t = new Thread (this, threadName);
         t.start ();
      }
   }

}

public class TestThread {
   public static void main(String args[]) {

      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
   }   
}

The question:

  • Does one have to change the way one designs classes just to be able
    to make use of threading?
  • If I already have a program built without threading, and want to
    introduce threading, I could have easily done so in C++. But here, it
    seems like I'll have to re-design the entire class or make it inherit
    from Runnable. Is this really how you work with Java threads or are
    you supposed to design it for threading right from the beginning
    instead of introducing it later?

One example of a class I'm using is this:

public class abc extends abcParent {
//many member variables and functions here

public calculateThreshold() {
    for(int i = 0; i<zillion; ++i) {
        doSomethingThatIsParallelizable();
    }
}//calculateThreshold

private doSomethingThatIsParallelizable() {
    while(something) {
        //do something else which is parallelizable
    }//while
}//doSomething

}//class

Using streams is apparently not really advisable, so how does one go about designing a class for threading? It doesn't seem logical for abc to have start and run functions. That's silly. abc is about abc's functionality alone. I'd call abcInstance.calculateThreshold(); and it'd make sense, but calling abcInstance.run() instead of calculateThreshold() doesn't have the same readability. What would you advise?

Best Answer

These two APIs are almost exactly the same. The difference is the lack of templates and operator overloading, and the fact you need to call start() on Java's Thread objects.

The C++ std::thread constructor is a template that takes a function. The interface for function is "()" -- that can be a plain old function, or an object (such as a lambda or other std::function) which has overloaded operator().

Java's Thread takes an object that has subclassed Runnable and implemented Run(). It's the same pattern, except there's no templates, meaning there needs to be a base class, and no operator overloading so the method you implement is named Run() and not operator ().

You're right, though, that in Java (and in C++!) you will typically want to separate the logic for handling threading from the actual computation. One common approach is to have a threadpool. That lets you bound the number of parallel threads running -- it doesn't make sense to run a zillion separate threads -- and keeps you from needing to pay startup/teardown costs of a single thread a zillion times.

Unlike in C++ (so far) Java's standard library has a thread pool implementation already. java.lang.concurrent.ThreadPoolExecutor would work quite nicely here -- calculateThreshold() enqueues items into its queue, where each item is a Runnable that just calls doSomethingThatIsParallelizable().