Node:Another multi threaded example (Prolog top level), Previous:Multi threaded example, Up:Calling Prolog from Java
This is another multi threaded version of the train
example.
See Train, for information about how the train.sav
file is
created.
In this example prolog is the toplevel and Java is invoked via
library(jasper)
.
MultiSimple2.java:
import se.sics.jasper.Jasper; import se.sics.jasper.Query; import se.sics.jasper.Prolog; import se.sics.jasper.SICStus; import java.util.ArrayList; import java.util.HashMap; import java.util.ListIterator; public class MultiSimple2 { class Client extends Thread { Prolog jp; SICStus sp; String qs; Client(Prolog p, SICStus s, String queryString) { jp = p; sp = s; qs = queryString; } public void run() { HashMap WayMap = new HashMap(); try { synchronized(jp) { Query query = jp.openPrologQuery(qs, WayMap); try { while (query.nextSolution()) { System.out.println(WayMap); } } finally { query.close(); } } } catch ( Exception e ) { e.printStackTrace(); } } } class Watcher extends Thread { SICStus mySp; ArrayList threadList = new ArrayList(2); public boolean add(Client cl) { return threadList.add((Object)cl); } boolean at_least_one_is_alive(ArrayList tl) { ListIterator li = tl.listIterator(); boolean f = false; while (li.hasNext()) { boolean alive = ((Client)(li.next())).isAlive(); f = f || alive; } return f; } public void run() { while (at_least_one_is_alive(threadList)) { try { this.sleep(1000); } catch (InterruptedException ie) { System.err.println("Watcher interrupted."); } } mySp.stopServer(); } Watcher(SICStus sp) { mySp = sp; } } public void CallBack() { try { SICStus sp = SICStus.getCaller(); // get the SICStus object sp.load("train.ql"); Prolog jp = sp.newProlog(); // Create a new Prolog Interface Client c1 = new Client(jp, sp, "connected('Orebro', 'Hallsberg', Way1, Way1)."); c1.start(); // The prolog variable names in the Map are different from above so // we can tell which query gives what solution. Client c2 = new Client(jp, sp, "connected('Stockholm', 'Hallsberg', Way2, Way2)."); c2.start(); Watcher w = new Watcher(sp); w.add(c1); w.add(c2); w.start(); sp.startServer(); // And finally start the server. This // method call does not return until // some other thread calls sp.stopServer(). } catch ( Exception e ) { e.printStackTrace(); } } }
multisimple2.pl:
:- use_module(library(jasper)). main:- jasper_initialize(JVM), jasper_new_object(JVM, 'MultiSimple2', init, init, Obj), jasper_call(JVM, method('', 'CallBack', [instance]), 'CallBack'(+object('')), 'CallBack'(Obj)).
CallBack
is called, we cannot use Jasper.newProlog
to
obtain a Prolog
interface. Instead we can use the SICStus
method getCaller
to get a handle on the SICStus
object.
restore
method to load the
prolog saved state, since it unloads all foreign resources. This
includes library(jasper)
from which the call to Java was made.
Instead the method SICStus.load
can be used to load a compiled
prolog file. See the HTML Jasper documentation for details on this
method.
startServer
is to return. See the HTML Jasper documentation on the methods
SICStus.startServer
and SICStus.stopServer
.