Мой честный, профессиональный совет: не пытайтесь использовать многопоточность для этой проблемы.
Научитесь сначала писать понятный, надежный однопоточный код. Узнайте, как его отладить. Узнайте, как написать одно и то же разными способами. Только тогда вы можете начать вводить огромную сложность, которая является многопоточностью, и иметь все шансы, что она будет правильной.
И учиться, читая о том, как правильно писать многопоточный кодКакие проблемы выигрывают от многопоточности. Эта проблема не возникает, потому что вам нужен результат предыдущей арифметической операции в качестве входных данных для следующего.
Я отвечаю только из-за ужасного совета в комментариях использовать глобальные переменные. Не . Это не очень хороший способ написания многопоточного кода, даже в таком простом примере. Даже в однопоточном коде изменяемое глобальное состояние - это то, чего следует избегать, если это вообще возможно.
Держите изменяемое состояние как можно жестче под контролем. Создайте 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
переменная. Если, скажем, вы хотите выполнить второй расчет, вам не нужно беспокоиться о том, какое предыдущее состояние все еще находится в процессе: вам не нужно ничего сбрасывать перед другим запуском;Вы можете вызывать этот код параллельно, если хотите, без помех между запусками.
Но весь этот цикл можно было бы написать более чисто - и быстрее - с помощью простого вызова метода:
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 */
.