0

My program is calling the mathematical solver CPLEX multiple times. There is the possibility of setting a time limit for each time CPLEX is being executed from java, which I am using. The problem is that in some rare instances my program gets just stuck inside the .solve() method provided by CPLEX. I don't know where that fault lies, it is definitely not in the mathematical model I am solving, because exporting it and solving it outside of java works. But this is not what my question is about, although of course I'd be thankful for your input on that, too.

My question is: How can I make my program leave the .solve() method immediately no matter what? In the example below I tried to fix this problem. There, the .solve() method is called in the method execute().

public synchronized void executeSafely(int limitSeconds) {
    Thread t = new Thread() {
        @Override
        public void run() {
            execute();
        }
    };
    t.start();
    try {
        Thread.sleep(3000 * limitSeconds);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    t.interrupt();
}

This approach does not work because there is no check for interruption inside the .solve() method and I cannot change that method. Replacing .interrupt() with .stop() does not work either since this leads to the suspension of the thread because of exception ThreadDeath.

So is there any other way of immediately terminating the execution of an external program?

tripleJ
  • 21
  • 6
  • 1
    Nope. There is no way. Unless the `Thread` is _interruptible_ there is no way to terminate it. [`Thread.stop`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#stop--) is deprecated because more often than not it will cause a spectacular blow-up rather than anything useful. – Boris the Spider Oct 05 '16 at 15:17
  • Are you launching the "external program" as a separate process, or calling methods in a library? – Andy Thomas Oct 05 '16 at 15:18
  • I have imported the cplex.jar library, the `.solve` method is in there. Here's what eclipse has to say about that method: `boolean ilog.cplex.IloCplex.solve() throws IloException Note: This element neither has attached source nor attached Javadoc and hence no Javadoc could be found.` – tripleJ Oct 05 '16 at 15:43
  • @tripleJ Take a look at https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html and answer to the following question: http://stackoverflow.com/questions/2758612/executorservice-that-interrupts-tasks-after-a-timeout I think it is exactly what you need – Sergi Oct 05 '16 at 16:01
  • 1
    @Sergi that just **interrupts** the process - there is no magic in `Future.cancel(true)`. If the process is not listening to interrupts/cannot be interrupted then this does absolutely nothing. – Boris the Spider Oct 05 '16 at 16:05
  • @BoristheSpider Yes, you are right. Sorry, was inattentive while reading the question. – Sergi Oct 05 '16 at 16:21
  • This applies specifically to CPLEX and the `solve()` method, not your main question. Have you tried using [IloCplex.Aborter](http://www.ibm.com/support/knowledgecenter/SSSA5P_12.6.3/ilog.odms.cplex.help/refjavacplex/html/ilog/cplex/IloCplex.Aborter.html)? An example of how this is used is included in the MIPex4.java example that is shipped with CPLEX. – rkersh Oct 05 '16 at 23:35
  • @rkersh Thank you, that seems to work! – tripleJ Oct 06 '16 at 14:58
  • @tripleJ I presume you have already tried cplex.setParam(IloCplex.DoubleParam.TiLim, TIME_IN_SECONDS) method? – Michał Urbaniak Oct 13 '16 at 08:30

0 Answers0