All Downloads are FREE. Search and download functionalities are using the official Maven repository.

carosellini.rJava.JRI.0.9-7.source-code.Mutex Maven / Gradle / Ivy

Go to download

JRI is a Java/R Interface, which allows to run R inside Java applications as a single thread. Basically it loads R dynamic library into Java and provides a Java API to R functionality. It supports both simple calls to R functions and a full running REPL.

The newest version!
package org.rosuda.JRI;

/** This class implements a (not so) simple mutex. The initial state of the mutex is unlocked. */
public class Mutex {
    public static boolean verbose=false;

    /** defines the current mutex state */
    private boolean locked=false;

    /** thread that locked this mutex (used for simple deadlock-detection) */
    private Thread lockedBy=null;

    /** locks the mutex. If the mutex is already locked, waits until the mutex becomes free. Make sure the same thread doesn't issue two locks, because that will cause a deadlock. Use {@link #safeLock()} instead if you wish to detect such deadlocks. */
    public synchronized void lock()
    {
        while (locked) {
            if (lockedBy==Thread.currentThread())
                System.err.println("FATAL ERROR: org.rosuda.JRI.Mutex detected a deadlock! The application is likely to hang indefinitely!");
            if (verbose)
                System.out.println("INFO: "+toString()+" is locked by "+lockedBy+", but "+Thread.currentThread()+" waits for release (no timeout)");
            try {
                wait();
            } catch (InterruptedException e) {
                if (verbose)
                    System.out.println("INFO: "+toString()+" caught InterruptedException");
            }
        }
        locked=true;
        lockedBy=Thread.currentThread();
        if (verbose) System.out.println("INFO: "+toString()+" locked by "+lockedBy);
    }

    /** locks the mutex. If the mutex is already locked, waits until the mutex becomes free. Make sure the same thread doesn't issue two locks, because that will cause a deadlock.
        @param to timeout in milliseconds, see {@link #wait()}.
        @return true if the lock was successful, false if not
        */
    public synchronized boolean lockWithTimeout(long to)
    {
        if (locked) {
            if (lockedBy==Thread.currentThread())
                System.err.println("FATAL ERROR: org.rosuda.JRI.Mutex detected a deadlock! The application is likely to hang indefinitely!");
            if (verbose)
                System.out.println("INFO: "+toString()+" is locked by "+lockedBy+", but "+Thread.currentThread()+" waits for release (timeout "+to+" ms)");
            try {
                wait(to);
            } catch (InterruptedException e) {
                if (verbose)
                    System.out.println("INFO: "+toString()+" caught InterruptedException");
            }
        }
        if (!locked) {
            locked=true;
            lockedBy=Thread.currentThread();
            if (verbose) System.out.println("INFO: "+toString()+" locked by "+lockedBy);
            return true;
        }
        if (verbose) System.out.println("INFO: "+toString()+" timeout, failed to obtain lock for "+Thread.currentThread());
        return false;
    }

    /** attempts to lock the mutex and returns information about its success.
        @return 0 if the mutex was locked sucessfully
1 if the mutex is already locked by another thread
-1 is the mutex is already locked by the same thread (hence a call to {@link #lock()} would cause a deadlock). */ public synchronized int tryLock() { if (verbose) System.out.println("INFO: "+toString()+" tryLock by "+Thread.currentThread()); if (locked) return (lockedBy==Thread.currentThread())?-1:1; locked=true; lockedBy=Thread.currentThread(); if (verbose) System.out.println("INFO: "+toString()+" locked by "+lockedBy); return 0; } /** Locks the mutex. It works like {@link #lock()} except that it returns immediately if the same thread already owns the lock. It is safer to use this function rather than {@link #lock()}, because lock can possibly cause a deadlock which won't be resolved. @return true is the mutex was successfully locked, false if deadlock was detected (i.e. the same thread has already the lock). */ public synchronized boolean safeLock() { if (locked && lockedBy==Thread.currentThread()) { if (verbose) System.out.println("INFO: "+toString()+" unable to provide safe lock for "+Thread.currentThread()); return false; } lock(); return true; } /** Locks the mutex. It works like {@link #lockWithTimeout(long)} except that it returns immediately if the same thread already owns the lock. It is safer to use this function rather than {@link #lockWithTimeout(long)}, because lock can possibly cause a deadlock which won't be resolved. @return true is the mutex was successfully locked, false if deadlock was detected or timeout elapsed. */ public synchronized boolean safeLockWithTimeout(long to) { if (locked && lockedBy==Thread.currentThread()) { if (verbose) System.out.println("INFO: "+toString()+" unable to provide safe lock (deadlock detected) for "+Thread.currentThread()); return false; } return lockWithTimeout(to); } /** unlocks the mutex. It is possible to unlock an unlocked mutex, but a warning may be issued. */ public synchronized void unlock() { if (locked && lockedBy!=Thread.currentThread()) System.err.println("WARNING: org.rosuda.JRI.Mutex was unlocked by other thread than locked! This may soon lead to a crash..."); locked=false; if (verbose) System.out.println("INFO: "+toString()+" unlocked by "+Thread.currentThread()); // notify just 1 in case more of them are waiting notify(); } public String toString() { return super.toString()+"["+((locked)?"":"un")+"locked"+((!locked)?"":(", by "+((lockedBy==Thread.currentThread())?"current":"another")+" thread"))+"]"; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy