Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting a Java Thread's Runnable after construction

The JDK 7 Java docs suggest the following two idioms for creating Java threads:

  1. Extend Thread and override run()

    class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;
     }
    
     public void run() {
         // compute primes larger than minPrime
          . . .
     }
    }
    
    ...
    
    //And to launch the custom Thread
    
    PrimeThread p = new PrimeThread(143);
    
    p.start();
    
  2. Implement Runnable and create a new Thread passing the Runnable impl into its constructor

    class PrimeRun implements Runnable {
     long minPrime;
     PrimeRun(long minPrime) {
         this.minPrime = minPrime;
     }
    
     public void run() {
         // compute primes larger than minPrime
          . . .
     }
    }
    
    ...
    
    //And to launch a new Thread with this Runnable's behavior
    
    PrimeRun p = new PrimeRun(143);
    
    new Thread(p).start();
    

These are fine enough, but I'd like to be able to create a subclass of Thread and then define and set its Runnable implementation sometime later (e.g. not just in the Thread's constructor). From what I can tell, Java's Thread class does not provide a means to accomplish this so I came up with the following:

public class FlexiThread extends Thread{


//The Runnable impl to be executed
private Runnable mvRunner;

//Construct an empty subclass of Thread
public FlexiThread(){
    super();

}

//Construct a subclass of Thread which provides 
//its Runnable impl immediately
public FlexiThread(Runnable r){
    super(r);
    mvRunner = r;

}

/**
 * 
 * @return -- the Runnable implementation whose 
 * run() method will be invoked when this thread
 * is started
 */
public Runnable getRunnableToExecute(){
    return mvRunner;
}
/**
 * @param runner -- the Runnable implementation whose 
 * run() method will be invoked when this thread
 * is started
 */ 
public void setRunnableToExecute(Runnable runner){
    mvRunner = runner;
}


@Override
public void run(){
    mvRunner.run();
}

}

I tested FlexiThread and it appears to work as expected (it executes whatever code I give in the Runnable impl's run method in a separate thread of execution verified via DDMS) at least on Android ICS and JB; is there anything wrong/potentially dangerous/inefficient with the FlexiThread strategy given above? If so, what might be a better way to define a Thread subclass's Runnable after its construction?

like image 293
CCJ Avatar asked May 31 '13 15:05

CCJ


1 Answers

I would use an Executor as this is re-useable and controlable.

ExecutorService es = Executors.newSingleThreadedPool();

// set a runnable later.
es.submit(new MyRunnable());

// give it another runnable when that finishes.
es.submit(new MyRunnable2());

// don't need it any more
es.shutdown();
like image 69
Peter Lawrey Avatar answered Sep 28 '22 09:09

Peter Lawrey