/*
 * Copyright 1997-2021 Optimatika
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package org.ojalgo.concurrent;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

import org.junit.jupiter.api.Test;
import org.ojalgo.TestUtils;

public class ProcessingServiceTest {

    private static final int _100 = 100;

    @Test
    public void testCompute() {

        ProcessingService executor = ProcessingService.newInstance("Test-compute");

        List<BigDecimal> inputs = new ArrayList<>();
        for (int i = 0; i < _100; i++) {
            inputs.add(BigDecimal.valueOf(i));
        }

        Map<BigDecimal, BigDecimal> results = executor.compute(inputs, Parallelism.THREADS, item -> item.movePointRight(1));

        TestUtils.assertEquals(_100, results.size());
        for (Entry<BigDecimal, BigDecimal> entry : results.entrySet()) {
            TestUtils.assertEquals(entry.getKey(), entry.getValue().divide(BigDecimal.TEN));
        }
    }

    @Test
    public void testProcess() {

        ProcessingService executor = ProcessingService.newInstance("Test-process");

        List<BigDecimal> inputs = new ArrayList<>();
        for (int i = 0; i < _100; i++) {
            inputs.add(BigDecimal.valueOf(i));
        }

        LongAdder counter = new LongAdder();
        Set<BigDecimal> seen = ConcurrentHashMap.newKeySet(_100);

        executor.process(inputs, Parallelism.THREADS, item -> {
            seen.add(item);
            counter.increment();
        });

        TestUtils.assertEquals(_100, counter.sum());
        TestUtils.assertEquals(_100, seen.size());

        for (BigDecimal input : inputs) {
            TestUtils.assertTrue(seen.contains(input));
        }
    }

    @Test
    public void testRun() {

        ProcessingService executor = ProcessingService.newInstance("Test-run");

        AtomicInteger counter = new AtomicInteger();

        executor.run(Parallelism.THREADS, () -> {

            while (counter.get() < _100) {
                if (counter.incrementAndGet() >= _100) {
                    return;
                }
            }
        });

        TestUtils.assertEquals(_100, counter.get());
    }

}

@@ -1548,44 +1548,365 @@
     
-private static final int _100 = 100;
+static final int DIM = 100;%0A    static final Object LOCK = new Object();%0A%0A    static void increment(final AtomicInteger counter) %7B%0A        while (counter.get() %3C DIM) %7B%0A            synchronized (LOCK) %7B%0A                if (counter.get() %3C DIM && counter.incrementAndGet() %3E= DIM) %7B%0A                    return;%0A                %7D%0A            %7D%0A        %7D%0A    %7D
 %0A%0A  
@@ -2104,36 +2104,35 @@
 (int i = 0; i %3C 
-_100
+DIM
 ; i++) %7B%0A       
@@ -2339,20 +2339,19 @@
 tEquals(
-_100
+DIM
 , result
@@ -2753,20 +2753,19 @@
  0; i %3C 
-_100
+DIM
 ; i++) %7B
@@ -2927,20 +2927,19 @@
 wKeySet(
-_100
+DIM
 );%0A%0A    
@@ -3095,36 +3095,35 @@
 ls.assertEquals(
-_100
+DIM
 , counter.sum())
@@ -3155,20 +3155,19 @@
 tEquals(
-_100
+DIM
 , seen.s
@@ -3516,70 +3516,113 @@
  -%3E 
-%7B%0A%0A            while (counter.get() %3C _100) %7B%0A        
+ProcessingServiceTest.increment(counter));%0A%0A        TestUtils.assertEquals(DIM, counter.get());%0A%0A
         
 if (
@@ -3617,28 +3617,24 @@
         
-if (
 counter.
 incremen
@@ -3629,106 +3629,95 @@
 ter.
-incrementAndGet() %3E= _100) %7B%0A                    return;%0A                %7D%0A            %7D%0A        %7D
+set(0);%0A%0A        executor.run(() -%3E DIM, () -%3E ProcessingServiceTest.increment(counter)
 );%0A%0A
@@ -3751,12 +3751,11 @@
 als(
-_100
+DIM
 , co

Update ProcessingServiceTest.java