Install Java-Thread Runnable after build

The JDK 7 Java documentation offers the following two idioms for creating Java threads:

  • 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(); 
  • Deploy Runnable and create a new thread that passes the Runnable impl to your 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 behavior PrimeRun p = new PrimeRun(143); new Thread(p).start(); 

This is good enough, but I would like to create a subclass of Thread, and then define and install its Runnable implementation after some time (for example, not only in the Thread constructor). From what I can say, the Java Thread class provides no means to achieve 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 seems to work as expected (it executes any code that I provide in the Runnable impl run method in a separate thread of execution, verified through DDMS), at least on Android ICS and JB; Is there anything wrong / potentially dangerous / ineffective with the FlexiThread strategy above? If so, what could be the best way to define Thread Runable subclasses after building it?

+4
source share
2 answers

I would use Executor as it can be reused and controlled.

 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(); 
+7
source

is there something wrong / potentially dangerous / ineffective with the above FlexiThread strategy

I would say no, this is good, although it seems to me dangerous to build a thread that cannot be fully run. Of course, you should add good code comments explaining what is going on. I would also add some good message throws when you try to start a thread if mvRunner not installed.

One improvement is not stream expansion, but the creation of FlexiRunnable instead:

 public class FlexiRunnable implements Runnable { private Runnable delegate; private volatile boolean running = false; public void run() { running = true; if (delegate != null) { delegate.run(); } } public void setDelegate(Runnable delegate) { if (running) { throw new IllegateStateException("The thread is already running..."); } this.delegate = delegate; } } ... FlexiRunnable flexi = new FlexiRunnable(); Thread thread = new Thread(flexi); ... flexi.setDelegate(...); thread.start(); 
+2
source

Source: https://habr.com/ru/post/1483825/


All Articles