commons-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marcus Deluigi <mdelu...@student.ethz.ch>
Subject Javaflow: suspending a thread from outside the thread
Date Tue, 01 Aug 2006 19:09:26 GMT
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: commons-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-user-help@jakarta.apache.org


Mime
View raw message