Run your second application under the fixed priority class and with it the lowest possible priority. If it is already running, you can set it using its pid:
priocntl -c FX -m 0 -p 0 -s -i pid <pid>
Or do it at launch time:
priocntl -c FX -m 0 -p 0 -e command [arguments ...]
Note that the FX scheduling class shouldn't be confused with the RT one. While the RT (Real Time) priority class is also a fixed priority class, the processes being granted a RT priority will preempt system threads (i.e. the kernel) so should only be used with processes with relatively short compute activity periods. The RT class is absolutely not recommended for a process requiring 100 CPU threads for an extended period of time like the one you describe. This issue does not exist with the FX class which (default) range of priorities is the same as the regular time sharing ones.
As Yedric noted in his reply, setting the low priority process priority to 0 is not enough to make sure it won't run at all when the high priority one is active.
The reason is the latter being in the time sharing class, the scheduler will notice a process has been waiting for a while so will reduce the actual priority of the critical process down to 0, allowing small bursts of activity from the low priority process.
To avoid this situation, you can set the critical process to the FX class with a median priority. In such case, it will never yield to the other one:
priocntl -c FX -m 30 -p 30 -c critical_command ...