编写一个 Java 程序,使用线程来计算忽略操作顺序的表达式?

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

我正在尝试编写一个 Java 程序,该程序使用线程来计算表达式,例如:

3 + 4 / 7 + 4 * 2

并输出

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

在这个练习中,我们忽略了操作顺序。表达式是通过用户输入输入的。目标是让一个单独的线程来执行每个计算。正如我在上面列出的那样,我绝对希望每个线程都执行每个单独的计算。

我诚实、专业的建议是不要尝试使用多线程来解决这个问题。

先学习编写清晰、健壮的单线程代码。学习如何调试它。了解如何以多种不同的方式编写相同的内容。只有到那时,您才能开始介绍多线程的 巨大 复杂性,并且有可能是正确的。

并通过阅读如何正确编写多线程代码来了解多线程可以解决哪些问题。本题不会,因为你需要上一个算术运算的结果作为下一个的输入。

我之所以回答,是因为评论中关于使用全局变量的糟糕建议。 不要。这不是编写多线程代码的好方法,即使在这样一个简单的示例中也是如此。即使在单线程代码中,也应该尽可能避免可变的全局状态。

尽可能严格地控制可变状态。创建一个 Runnable 子类,其中包含您要执行的操作:

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` */;
  }
}

现在,您可以使用以下方法计算 1 + 2

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

(或者,您可以使用 int result = 1 + 2;...)

所以你现在可以循环使用它了:

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;
}

所有可变状态都限制在op变量的范围内。比方说,如果你想要 运行 第二次计算,你不必担心之前的状态仍然存在:你不必在另一个 运行 之前重置任何东西;如果需要,您可以并行调用此代码,而不会在 运行s.

之间产生干扰

但是可以使用一个简单的方法调用将所有循环写得更干净、更快:

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

其中method是一个包含/* code to calculate operand1 (oprator) operand2 */的方法。