Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
    
Aside: Your c++ example is not a good way to use c++11 mutexes. Think of calling m.unlock() as equivalent to calling delete. Just as every call to delete is a sign of a potential problem in modern c++ code, so is every call to m.unlock(). Use a std::lock_guard or a std::unique_lock. – David Hammen Mar 14 at 9:19
    
Ah the example I had just copied from the popular mutex tutorial on the internet. While the use of smart-pointer-protected locks is better, it'd help to know that there are some applications (like one I worked on), which needs such fast processing, that smart pointers actually slow down the program by a third. We had to replace boost pointer containers with a simple array implementation and noticed a huge improvement in performance. For smart pointer mutexes also, one man's meat is another man's poison. – Nav Mar 14 at 9:30
up vote 2 down vote accepted

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().

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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