I am running several subtasks in parallel with Ant.
This is the simplified content of build.xml:
<target name="parallelOperations">
<var name="port.number" value="9006"/>
<for list="a,b,c,d,e" param="letter" parallel="true">
<sequential>
<echo>Letter @{letter}</echo>
<math result="port.number" operand1="${port.number}" operation="+" operand2="1" datatype="int"/>
<echo>${port.number}</echo>
</sequential>
</for>
</target>
This is the main result:
[echo] Letter c
[echo] Letter b
[echo] Letter a
[echo] Letter d
[echo] Letter e
[echo] 9007
[echo] 9007
[echo] 9007
[echo] 9007
[echo] 9007
What happens here is for each element of the list, it prints the content of the element and the result of plus operation. The problem here is the math operation is not thread-save, means that every operation accesses the variable $port.number concurrently, adds one value, and then assigns the value.
Is there anyway to do it thread-safe with Ant? What I try to do is per each subtask which runs in parallel, get an unique port number. If there is any other way to do it, it could be also good solution.
This is from the documentation of parallel
:
The primary use case for
<parallel>
is to run external programs such as an application server, and the JUnit or TestNG test suites at the same time. Anyone trying to run large Ant task sequences in parallel, such as javadoc and javac at the same time, is implicitly taking on the task of identifying and fixing all concurrency bugs the tasks that they run.
Therefore synchronizing the operation is up to the user. There are potentially two solutions:
Either use the waitfor
task to make each thread to wait for a certain condition to be true (e.g. a property is set).
Implement your own synchronization task. This link describes a way to write a task that can take an id and locks on it.
The first solution is more simple and is generally intended for this kind of synchronization.