NIket
NIket

Reputation: 924

Returning value from a running thread & keep thread running

I am developing an application in java which has two classes and one executor class. I am running these both classes with two different daemon threads. Now I want to return a value from this two thread to my executor class & thread should not stop. So how can I do such thing with java so that thread will send value to caller class and it will not stop its working. second thing is that how I will take that value from caller i.e executor class as I am starting thread just by t.start();

Poll Class

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;
public class Poll {
    File f = null;
    String path;
    long currentTime;
    long oldTime=0;
    int polltimer=0;
    private static Poll instance = null;
    public Poll()
    {
        polltimer=60000;
    }
    public  static GatewayTrigger getInstance() {
        if(instance == null)
            instance = new Poll();
        return instance;
    }
    public void startTrigger(String file)
    {
        f = new File(file);
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                makePoll();
            }
        }, 1000,polltimer);
    }
    public void makePoll()
    {
        currentTime = f.lastModified();
        if(oldTime==0)
            oldTime=currentTime;
        if(oldTime!=currentTime)
        {
            System.out.print("Event Found");
            ExecutorwithClass.pollEvent="Event Found";
            oldTime=currentTime;
        }
    }
}

Push Class

public class Push {
    private static  Push instance = null;
    public  static GatewayTrigger getInstance() {
        if(instance == null)
            instance = new Push();
        return instance;
    }
    public void startTrigger(String path) {
        try {
            WatchService watcher = FileSystems.getDefault().newWatchService();
            Path dir = Paths.get(path);
            dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
            while (true) {
                WatchKey key;
                try {
                    key = watcher.take();
                } catch (InterruptedException ex) {
                    return;
                }
                for (WatchEvent<?> event : key.pollEvents()) {
                    WatchEvent.Kind<?> kind = event.kind();
                    @SuppressWarnings("unchecked")
                    WatchEvent<Path> ev = (WatchEvent<Path>) event;
                    Path fileName = ev.context();
                    System.out.println(kind.name() + ": " + fileName);
                    ExecutorwithClass.pushEvent=kind.name()+" : "+fileName;
                }
                if (!key.reset()) {
                    break;
                }
            }
        } catch (Exception ex) {
            System.err.println(ex);
        }
    }
}

Executor class

public class ExecutorwithClass {
    Thread pushThread,pollThread;
    File f = null;
    String path;
    long currentTime;
    long oldTime=0;
    int polltimer=0;
    Poll poll;
    Push push;
    static String pollEvent="",pushEvent="";
    public ExecutorwithClass() {
        poll= (Poll) Poll.getInstance();
        push= (Push) Push.getInstance();
        pushThread=new Thread() {
            public void run () {
                poll.startTrigger("");
            }
        };
        pushThread.setDaemon(true);
        pollThread=new Thread() {
            public void run () {
                push.startTrigger("");
            }
        };
        pollThread.setDaemon(true);
        pushThread.start();
        pollThread.start();
    }
    public JSONArray sendPollOutput()
    {
        JSONArray result = new JSONArray();
        JSONObject obj = new JSONObject();
        try {
            obj.put("Output",pollEvent);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        result.put(obj);
        return result;
    }
    public JSONArray sendPushOutput()
    {
        JSONArray result = new JSONArray();
        JSONObject obj = new JSONObject();
        try {
            obj.put("Output",pushEvent);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        result.put(obj);
        return result;
    }
}

Upvotes: 2

Views: 1935

Answers (6)

Krzysztof Cichocki
Krzysztof Cichocki

Reputation: 6412

Can't you use the notifier/listener pattern? You could just give the thread an object which it should callback when the thread need to notify something.

class MyRunnable extends Runnable {

    private MyRunnableListener listener;

    public MyRunnable(MyRunnableListener listener) {
       this.listener=listener;
    }

    public void run() {
       while(true) {
          // do some job
          somethingInteresting = ...
          if (hasSomethingInetresting) {
              listener.somethingForYou(somethingInteresting);
          }
       }
    }
}
class MyRunnableListener {

    public void somethingForYou(SomethingInteresting somethingInteresting) {
         // do your job with "somethingInteresting"
    }

}

And you just do it like that:

MyRunnableListener listener = new MyRunnableListener();

MyRunnable myRunnable = MyRunnable(listener );

Executor executor = ...
executor.submit(myRunnable);

Upvotes: 0

raulk
raulk

Reputation: 2869

Instantiate a Queue from your main Executor class and pass it to your Thread/Runnable via a constructor or a setter.

It can then use this Queue to send objects or messages back to the main executor.

This is the basic principle of message passing or the actor model.

If you're using Java 8, you can also look into using a stream.

Upvotes: 0

Bahramdun Adil
Bahramdun Adil

Reputation: 6089

It is the customer and the producer design. Which you can let thread1 to wait until thread2 does the job, and notify the thead1 and then wait to thread2 finishes the job and then notify the thread2 ... and so on

As you say that you want the get some result value from the threads, then you can do like this:


  |                                                          |
  t1                                                         t2
if(some condation) {
  new Thread(new Runnable() {
     // call the method of the caller class
  }).start();
}

Upvotes: 0

matt
matt

Reputation: 12346

I am partial to queues. Similar to AWT's EventQueue.

final Queue<Message> messages = new ConcurrentLinkedQueue<>();
Thread a = new Thread(()->{
    while(true){
        Message message;
        //do stuff and create your message.
        messages.add(message);

    }
});
a.start();
Thread b = new Thread(()->{
   while(true){
       while(messages.size()>0){
          processMessage(messages.poll());
       }
       //do other stuff.
   } 
});
b.start();

Upvotes: 2

Stugal
Stugal

Reputation: 880

I'm not sure if I understand correctly your problem, but the way i'd go around it would be to have some sort of thread safe object (e.g. queue or a list) in each thread and in it's run method place whatever objects in that queue or list. Each of this threads can then have a get method to give access to this underlying list/queues so that you can access them from elsewhere. So to sum up, thread does some job, put's an object in the queue, other object has access to that queue and can get something from it.

Upvotes: 0

Mr x
Mr x

Reputation: 868

You can keep static variable in your executor class & set value of this variable from your threaded class whenever required event occurs.

Upvotes: 0

Related Questions