This is documentation for Mathematica 5, which was
based on an earlier version of the Wolfram Language.
View current documentation (Version 11.2)

Documentation / Mathematica / Add-ons & Links / J/Link / Part 2. Writing Java Programs That Use Mathematica /

2.15 Threads, Blocking, and Yielding

The classes that implement the Mathlink and KernelLink interfaces are not thread-safe. This means that if you write a J/Link program in which one link object is used by more than one thread, you need to pay careful attention to concurrency issues. The relevant methods in the link implementation classes are synchronized, so at the individual method level there is no chance that two threads can try to use the link at the same time. However, this is not enough to guarantee thread safety because interactions with the link typically involve an entire transaction, encompassing a multistep write and read of the result. This entire transaction must be guarded. This is done by using synchronized blocks to ensure that the threads do not interfere with each other's use of the link.

The "evaluateTo" methods are synchronized, and they encapsulate an entire transaction within one call, so if you use only these methods you will have no concerns. On the other hand, if you use evaluate() and waitForAnswer(), or any other technique that splits up a single transaction across multiple method calls, you should wrap the transaction in a synchronized block, as follows:

synchronized (ml) {

    ml.evaluate("2+2");

    ml.waitForAnswer();

    int result = ml.getInteger();

}

Synchronization is only an issue if you have multiple threads using the same link.

J/Link functions that read from a link will block until data arrives on that link. For example, when you call evaluateToOutputForm(), it will not return until Mathematica has computed and returned the result. This might be a problem if the thread on which evaluateToOutputForm() was called needs to stay active—for example, if it is the AWT thread, which processes user interface events.

How to handle blocking is a general programming problem, and there are a number of solutions. The Java environment is multithreaded, and thus an obvious solution is simply to make J/Link calls on a thread that does not need to be continuously responsive to other events in the system.

MathLink has the notion of a "yield function," which is a function you can designate to be called from the internals of MathLink while MathLink is blocking, waiting for input to arrive from the other side. A primary use for yield functions was to solve the blocking problem on operating systems that did not have threads, or for programming languages that did not have portable threading libraries. The way this would typically work is that your single-threaded program would install a yield function that ran its main event loop, so that the program could process user interface events even while it was waiting for MathLink data.

With Java, this motivation goes away. Rather than using a yield function to allow your program's only thread to still handle events while blocking, you simply start a separate thread from the user interface thread and let it happily block inside J/Link calls. Despite the limited usefulness of yield functions in Java programs, J/Link provides the ability to use them anyway.

// From the MathLink interface

public boolean setYieldFunction(Class cls, Object obj, String methName);

The setYieldFunction() method in the MathLink interface takes three arguments that identify the function to be called. These arguments are designed to accommodate static and nonstatic methods, so only two of the three need to be specified. For a static method, supply the method's Class and its name, leaving the second argument null. For a nonstatic method, supply the object on which you want the method called and the method's name, leaving the Class argument null. The function must be public, take no arguments, and return a boolean, for example:

public boolean myYielder();

The function you specify will be called periodically while J/Link is blocking in a call that tries to read from the link. The return value is used to indicate whether J/Link should back out of the read call and return right away. Backing out of a read call will cause a MathLinkException to be thrown by the method that is reading from the link. This MathLinkException is recoverable (meaning that clearError() will return true), so you could call waitForAnswer() again later and get the result when it arrives if you want. Return false from the yield function to indicate that no action should be taken (thus false is the normal return value for a yield function), and return true to indicate that J/Link should back out of the reading call. To turn off the yield function, call setYieldFunction(null, null, null).

Very few J/Link programmers will have any need for yield functions. They are a solution to a problem that is better handled in Java by using multiple threads. About the only reasonable motivation for using a yield function is to be able to back out of a computation that is taking too long and either resists attempts to abort it, or you know you want to close the link anyway. This can also be done by calling abandonEvaluation() on a separate thread. The abandonEvaluation() method is described in the section "Aborting and Interrupting Computations." Note that abandonEvaluation() uses a yield function internally, so calling it will wipe out any yield function you might have installed on your own.