Another Jafaflow question (or maybe still the same):

I have a thread where a user should be able to suspend it at any time and another user should be able to resume it at any time.
The problem is now: how do I call the "suspend()" method?

I could make a public "suspend()" method within the thread that calls "Continuation.suspend();", but the problem is that the second user just gets a continuation object and has no reference to the actual thread.

So, the only way to communicate is through the context-object. But I just can set some flags within the context object. So only way that I can think of is to create a timer task, that periodically checks for the flag within the thread. But that means I have a thread within a thread and it seems that Javaflow can't deal with threads inside threads.

Here is a minimalistic example of how I think this should work:
------8<-----
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.javaflow.Continuation;

/**
 * An object with the thread context
 */
class Context {
    public boolean suspend = false;
}

/**
 * The thread with some work that should be suspended
 */
class FlowRunnable implements Runnable {

    public String test;

    private Timer timer;

    public FlowRunnable ( ) {
        timer = new Timer();
        timer.schedule( new SuspendCheck(), 1000, 1000 );
    }

    public void run () {
        System.out.println( "started!" );
        for ( int i = 0; i < 100; i++ )
            echo( i );
    }

    private void echo ( int i ) {
        System.out.println( i );
    }

    private void suspend () {
        Continuation.suspend();
    }

    class SuspendCheck extends TimerTask {
        public void run () {
            Context context = (Context) Continuation.getContext();
            if ( context.suspend ) {
                suspend();
            }
        }
    }

}

/**
 * This thread just implements some asynchronous behavior.
 */
class FlowAdministration implements Runnable {

    private Context context = new Context();

    private FlowRunnable job;

    private Continuation continuation;

    private boolean firsttime;

    private Thread thread;

    public FlowAdministration ( FlowRunnable job ) {
        this.job = job;
        this.continuation = null;
        firsttime = true;

        thread = new Thread( this );
        thread.start();
    }

    public FlowAdministration ( Continuation continuation ) {
        this.continuation = continuation;
        this.job = null;
        firsttime = false;

        thread = new Thread( this );
        thread.start();
    }

    public void run () {
        if ( firsttime )
            continuation = Continuation.startWith( job, context );
        else
continuation = Continuation.continueWith( continuation, context );
    }

    /**
* This is a very bad hack. Now, we don't want to have an asynchronous
     * behavior.
     *
     * @return The suspended thread
     */
    public Continuation suspend () {
        context.suspend = true;
        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException e ) {
        }
        return continuation;
    }

}

/**
 * Run the whole thing.
 *
 */
public class jafaflowTest {

    public static void main ( String[] args ) {
FlowAdministration admin = new FlowAdministration( new FlowRunnable() );
        try {
            // do some other stuff while the thread is running
            Thread.sleep( 2000 );
        } catch ( InterruptedException e ) {
        }

// we suddenly decide to suspend the thread, maybe upon a user input
        Continuation c = admin.suspend();
        System.out.println( "returned a continuation" );

        // and now we decide to continue it
        new FlowAdministration( c );
    }

}
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.javaflow.Continuation;

/**
 * An object with the thread context
 */
class Context {
    public boolean suspend = false;
}

/**
 * The thread with some work that should be suspended
 */
class FlowRunnable implements Runnable {

    public String test;

    private Timer timer;

    public FlowRunnable ( ) {
        timer = new Timer();
        timer.schedule( new SuspendCheck(), 1000, 1000 );
    }

    public void run () {
        System.out.println( "started!" );
        for ( int i = 0; i < 100; i++ )
            echo( i );
    }

    private void echo ( int i ) {
        System.out.println( i );
    }

    private void suspend () {
        Continuation.suspend();
    }

    class SuspendCheck extends TimerTask {
        public void run () {
            Context context = (Context) Continuation.getContext();
            if ( context.suspend ) {
                suspend();
            }
        }
    }

}

/**
 * This thread just implements some asynchronous behavior.
 */
class FlowAdministration implements Runnable {

    private Context context = new Context();

    private FlowRunnable job;

    private Continuation continuation;

    private boolean firsttime;

    private Thread thread;

    public FlowAdministration ( FlowRunnable job ) {
        this.job = job;
        this.continuation = null;
        firsttime = true;

        thread = new Thread( this );
        thread.start();
    }

    public FlowAdministration ( Continuation continuation ) {
        this.continuation = continuation;
        this.job = null;
        firsttime = false;

        thread = new Thread( this );
        thread.start();
    }

    public void run () {
        if ( firsttime )
            continuation = Continuation.startWith( job, context );
        else
continuation = Continuation.continueWith( continuation, context );
    }

    /**
* This is a very bad hack. Now, we don't want to have an asynchronous
     * behavior.
     *
     * @return The suspended thread
     */
    public Continuation suspend () {
        context.suspend = true;
        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException e ) {
        }
        return continuation;
    }

}

/**
 * Run the whole thing.
 *
 */
public class jafaflowTest {

    public static void main ( String[] args ) {
FlowAdministration admin = new FlowAdministration( new FlowRunnable() );
        try {
            // do some other stuff while the thread is running
            Thread.sleep( 2000 );
        } catch ( InterruptedException e ) {
        }

// we suddenly decide to suspend the thread, maybe upon a user input
        Continuation c = admin.suspend();
        System.out.println( "returned a continuation" );

        // and now we decide to continue it
        new FlowAdministration( c );
    }

}
------>8-----

On execution, I get the following error:

Exception in thread "main" java.lang.ClassCircularityError: org/ apache/commons/javaflow/bytecode/Continuable
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:124)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
....


Is there any solution to this?

I think it might be a design decision based upon thread safety that Continuation.suspend() is only callable within the thread, but I find lots of disadvantages in it.


Greetings,
Marcus

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to