-2

I am trying to author a Java program that uses threads to calculate an expression such as:

3 + 4 / 7 + 4 * 2

and outputs

Enter problem: 3 + 4 / 7 + 4 * 2
Thread-0 calculated 3+4 as 7
Thread-1 calculated 7/7 as 1
Thread-2 calculated 1+4 as 5
Thread-3 calculated 5*2 as 10
Final result: 10

In this exercise, we are ignoring order of operations. The expression is entered via user input. The goal is to get a separate thread to perform each calculation. I absolutely want each thread to perform each of the individual calculations, as I have listed above.

user12149354
  • 55
  • 1
  • 7
  • 1
    Step 1) forget about using threads. They are totally unnecessary for this. – Andy Turner Oct 07 '19 at 17:43
  • @AndyTurner ... I'm assuming it's for homework – xtratic Oct 07 '19 at 17:44
  • 1
    @user12149354 In the main thread, break the problem up into sub-problems then pass those sub-problems to run in their own threads. – xtratic Oct 07 '19 at 17:46
  • Please see https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question – GhostCat Oct 07 '19 at 17:52
  • @xtratic I will try that and post an edit - thank you. How can I break each part of the problem into a sub-problem, though? I am thinking of storing the answer to each part of the expression, and then passing that value to the next thread? – user12149354 Oct 07 '19 at 17:55
  • @GhostCat thank you for pointing me to that resource. I tried to edit my question to be more explicit about what I was looking for. – user12149354 Oct 07 '19 at 17:55
  • It is still pretty broad. But yes, separate concerns. Asking for your inputs is not at all related to your actual assignment. You see, to be faster with testing, you should have code that processes strings ... coming from somewhere. So that you can start with hardcoded examples. Only **later**, when things work as you expect, then you replace the fixed input with "user provided input"! – GhostCat Oct 07 '19 at 17:57
  • You need to get value from the thread, look into this https://stackoverflow.com/questions/9148899/returning-value-from-thread. – User_67128 Oct 07 '19 at 18:07
  • @ManojBanik Hi, I tried to implement the suggestion that you pointed me to...would you be able to look over my update and give me a bit more guidance? I am having a disconnect between getting the user input, evaluating the expression, and then getting a thread to return that value... – user12149354 Oct 07 '19 at 18:37
  • Use a global variable ( an array, probably one variable will be good, no need of array) to store the thread result before thread exit, then use the stored value for the next thread when you call it. – User_67128 Oct 07 '19 at 18:50
  • @ManojBanik so if I understand correctly, should I take the `tokens` array that is currently in my main method as global, and then store the parts of the expression in that array, and parse it? I think I am a little confused what you are referring to when you say "( an array, probably one variable will be good, no need of array)"? – user12149354 Oct 07 '19 at 19:24
  • Are you pomegranate? – Martin James Oct 08 '19 at 15:00

1 Answers1

1

My honest, professional advice is don't try to use multithreading for this problem.

Learn to write clear, robust single-threaded code first. Learn how to debug it. Learn how to write the same thing in lots of different ways. It is only then that you can start to introduce the enormous complexity that is multithreading, and stand any chance of it being correct.

And learn, by reading about how to write multithreaded code correctly, what problems benefit from multithreading. This problem does not, because you need the result of the previous arithmetic operation as an input to the next.

I am only answering because of the terrible advice in comments to use global variables. Don't. This is not a good way to write multithreaded code, even in such a simple example. Even in single-threaded code, mutable global state is something which should be avoided if at all possible.

Keep your mutable state as tightly controlled as you can. Create a Runnable subclass which holds the operation you are going to perform:

class Op implements Runnable {
  final int operand1, operand2;
  final char oprator;

  int result;

  Op(int operand1, char oprator, int operand2) {
    // Initialize fields.
  }

  @Override public void run() {
    result = /* code to calculate `operand1 (oprator) operand2` */;
  }
}

Now, you can calculate, say, 1 + 2 using:

Op op = new Op(1, '+', 2);
Thread t = new Thread(op);
t.start();
t.join();
int result = op.result;

(Or, you could have just used int result = 1 + 2;...)

So you can now use this in a loop:

String[] tokens = eqn.split(" ");
int result = Integer.parseInt(tokens[0]);
for (int t = 1; t < tokens.length; t += 2) {
  Op op = new Op(
      result,
      result, tokens[t].charAt(0), 
      Integer.parseInt(tokens[t+1]));
  Thread t = new Thread(op);
  t.start();
  t.join();    
  result = op.result;
}

All of the mutable state is confined to the scope of the op variable. If you, say, want to run a second calculation, you don't have to worry about what previous state is still hanging around: you don't have to reset anything before another run; you can invoke this code in parallel, if you want, without interference between runs.

But all of this loop could be written more cleanly - and faster - using a simple method call:

for (int t = 1; t < tokens.length; t += 2) {
  result = method(
      result,
      result, tokens[t].charAt(0), 
      Integer.parseInt(tokens[t+1]));
}

Where method is a method containing /* code to calculate operand1 (oprator) operand2 */.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Thank you for this feedback. I really appreciate it, especially after trying to use a global variable to solve this problem. Your solution worked for me perfectly as I was just confused about the organization of the code. – user12149354 Oct 08 '19 at 17:56