package com.google.ortools.samples;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Arrays;

import com.google.ortools.linearsolver.MPConstraint;
import com.google.ortools.linearsolver.MPObjective;
import com.google.ortools.linearsolver.MPSolver;
import com.google.ortools.linearsolver.MPSolver.OptimizationProblemType;
import com.google.ortools.linearsolver.MPSolver.ResultStatus;
import com.google.ortools.linearsolver.MPVariable;


public class MultiThreadTest {

  static { System.loadLibrary("jniortools"); }

  private final static boolean verboseOutput = false; //true;


  public static void main(String[] args) throws Exception {
    launchProtocol(10, 8, true);
    launchProtocol(10, 8, false);
    System.out.println("We are done!");
    return;
  }

  public static void launchProtocol(int wholeLoopAttmpts, int threadPoolSize, boolean runInParallel) throws Exception {

    for (int noAttmpt = 0; noAttmpt < wholeLoopAttmpts; noAttmpt++) {

      System.out.println(String.format("Attempt %d", noAttmpt));

      int maxThreads = threadPoolSize;

      List<SolverThread> threadList = new ArrayList<SolverThread>();

      for (int i = 0; i < maxThreads; i++) {
        SolverThread thread = new SolverThread();
        threadList.add(thread);
      }

      ExecutorService executor = Executors.newFixedThreadPool(maxThreads);

      if (runInParallel) {
          System.out.println("Launching thread pool");
        executor.invokeAll(threadList);
        for( SolverThread thread : threadList ) {
            System.out.println(thread.getStatusSolver().toString());
        }
      } else {

        for (SolverThread thread : threadList) {
          System.out.println("Launching single thread");
          executor.invokeAll( Arrays.asList(thread) );
            System.out.println(thread.getStatusSolver().toString());
        }
      }

      System.out.println("Attempt finalized!");
      executor.shutdown();

    }

    System.out.println("Now exiting");

  }

  private static MPSolver makeProblem() {

    MPSolver solver = new MPSolver(UUID.randomUUID().toString(), OptimizationProblemType.CBC_MIXED_INTEGER_PROGRAMMING);

    double infinity = MPSolver.infinity();

    // x1 and x2 are integer non-negative variables.
    MPVariable x1 = solver.makeIntVar(0.0, infinity, "x1");
    MPVariable x2 = solver.makeIntVar(0.0, infinity, "x2");

    // Minimize x1 + 2 * x2.
    MPObjective objective = solver.objective();
    objective.setCoefficient(x1, 1);
    objective.setCoefficient(x2, 2);

    // 2 * x2 + 3 * x1 >= 17.
    MPConstraint ct = solver.makeConstraint(17, infinity);
    ct.setCoefficient(x1, 3);
    ct.setCoefficient(x2, 2);

    if (verboseOutput) {
      solver.enableOutput();
    }

    return solver;

  }

  private final static class SolverThread implements Callable<MPSolver.ResultStatus> {

    private MPSolver.ResultStatus statusSolver;

    public SolverThread() {

    }

    @Override
    public ResultStatus call() throws Exception {
      MPSolver solver = makeProblem();
      statusSolver = solver.solve();

      // Check that the problem has an optimal solution.
      if ( MPSolver.ResultStatus.OPTIMAL.equals(statusSolver) ) {
        throw new RuntimeException("Non OPTIMAL status after solve.");
      }
      return statusSolver;

    }

    public MPSolver.ResultStatus getStatusSolver() {
      return statusSolver;
    }

  }

}
@@ -756,13 +756,30 @@
 ; //
-true;
+ To enable Cbc logging
 %0D%0A%0D%0A
@@ -883,75 +883,60 @@
     
-launchProtocol(10, 8, false);%0D%0A    System.out.println(%22We are done!
+System.out.println(%22Cbc multi thread test successful
 %22);%0D
@@ -1577,26 +1577,24 @@
 arallel) %7B%0D%0A
-  
         Syst
@@ -1631,24 +1631,24 @@
 ad pool%22);%0D%0A
+
         exec
@@ -1986,26 +1986,24 @@
 thread) );%0D%0A
-  
           Sy
@@ -2050,32 +2050,32 @@
 ).toString());%0D%0A
+
         %7D%0D%0A     
@@ -2164,24 +2164,24 @@
 %0A%0D%0A    %7D%0D%0A%0D%0A
-
     System.o
@@ -2203,16 +2203,39 @@
  exiting
+ multi thread execution
 %22);%0D%0A%0D%0A 
@@ -3710,8 +3710,10 @@
   %7D%0D%0A%0D%0A%7D
+%0D%0A

Fixing a few typos