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?
m.unlock()
as equivalent to callingdelete
. Just as every call todelete
is a sign of a potential problem in modern c++ code, so is every call tom.unlock()
. Use astd::lock_guard
or astd::unique_lock
.