简体   繁体   中英

Writing a Java program that uses threads to calculate an expression that ignores order of operations?

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.

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 */ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM