开发者

Thread end listener. Java

开发者 https://www.devze.com 2023-02-14 04:19 出处:网络
Are there any Listeners in Java to hand开发者_高级运维le that some thread have been ended? Something like this:

Are there any Listeners in Java to hand开发者_高级运维le that some thread have been ended? Something like this:

Future<String> test = workerPool.submit(new TestCalalble());
test.addActionListener(new ActionListener()               
   {                                                         
    public void actionEnd(ActionEvent e)               
    {                                                        
        txt1.setText("Button1 clicked");                        
    }                                                        
   });

I know, that it is impossible to deal like this, but I want to be notified when some thread ended.

Usually I used for this Timer class with checking state of each Future. but it is not pretty way. Thanks


There is CompletionService you can use.

CompletionService<Result> ecs
       = new ExecutorCompletionService<Result>(e);
ecs.submit(new TestCallable());
if (ecs.take().get() != null) {
    // on finish
}

Another alternative is to use ListenableFuture from Guava.

Code example:

ListenableFuture future = Futures.makeListenable(test);
future.addListener(new Runnable() {
 public void run() {
   System.out.println("Operation Complete.");
   try {
     System.out.println("Result: " + future.get());
   } catch (Exception e) {
     System.out.println("Error: " + e.message());
   }
 }
}, exec);

Personally, I like Guava solution better.


No. Such listener does not exist. But you have 2 solutions.

  1. Add code that notifies you that thread is done in the end of run() method
  2. Use Callable interface that returns result of type Future. You can ask Future what the status is and use blocked method get() to retrieve result


Here is a geekish listener. Highly unadvisible to use but, funny and clever

Thread t = ...
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        t.getThreadGroup().uncaughtException(t, e);//this is the default behaviour
    }       
    protected void finalize() throws Throwable{
        //cool, we go notified
      //handle the notification, but be worried, it's the finalizer thread w/ max priority
    }
});

The effect can be achived via PhantomRefernce better

hope you have a little smile :)


Side note: what you ask is NOT thread end, but task completion event and the best is overriding either decorateTask or afterExecute


Without adding a lot of extra code you can make a quick listener thread yourself as follows:

//worker thread for doings
Thread worker = new Thread(new Runnable(){ 
    public void run(){/*work thread stuff here*/}
});
worker.start();
//observer thread for notifications
new Thread(new Runnable(){
    public void run(){
    try{worker.join();}
    catch(Exception e){;}
    finally{ /*worker is dead, do notifications.*/}
}).start();


You can implement Observer Pattern to report completion.

public interface IRunComplete {
    public void reportCompletion(String message);
}

Let the Thread caller implement this interface.

and in run() method you call this method at the end. So now you exactly knows when this thread gonna end.

Try it. I am actually using this and it's working fine.


You have a join() method defined by Thread class for that. However, you don't have direct visibility to a thread executing your Callable in concurrency API case..


Use this Example:

public class Main {

    public static void main(String[] args) {

        CompletionListener completedListener = count -> System.out.println("Final Count Value: " + count);

        HeavyWorkRunnable job = new HeavyWorkRunnable(completedListener);

        Thread otherThread = new Thread(job);
        otherThread.start();

    }

    static class HeavyWorkRunnable implements Runnable {

        CompletionListener completionListener;

        public HeavyWorkRunnable(CompletionListener completionListener) {
            this.completionListener = completionListener;
        }


        @Override
        public void run() {

            int count = 0;

            for (int i = 0; i < 10; i++) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Clock Tick #"+i);

                count += 1;

            }

            if (completionListener != null) {
                completionListener.onCompleted(count);
            }
        }
    }

    @FunctionalInterface
    interface CompletionListener {

        void onCompleted(int count);

    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消