从正在运行的线程中返回值&保持线程运行

时间:2016-02-24 09:06:24

标签: java multithreading

我正在java中开发一个应用程序,它有两个类和一个执行器类。 我正在使用两个不同的守护程序线程运行这两个类。 现在我想从这两个线程返回一个值到我的执行器类&线程不应该停止。 那么我怎么能用java做这样的事情,以便线程将值发送给调用者类,它不会停止它的工作。 第二件事是我将如何从调用者中获取该值,即执行者类,因为我只是通过t.start()启动线程;

民意调查班

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;
        }
    }
}

推送课程

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);
        }
    }
}

执行者类

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;
    }
}

6 个答案:

答案 0 :(得分:2)

我偏袒队列。与AWT的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();

答案 1 :(得分:0)

是客户和生产者设计。您可以让thread1等到thread2完成工作,然后通知thead1,然后等待thread2完成工作,然后通知thread2 ......等等

正如你所说,你想从线程获得一些结果值,那么你可以这样做:

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

答案 2 :(得分:0)

您可以在执行者类中保留静态变量&amp;每当发生必要事件时,从线程类中设置此变量的值。

答案 3 :(得分:0)

我不确定我是否正确理解了您的问题,但我解决的方法是在每个线程中使用某种线程安全对象(例如队列或列表)它的run方法放置该队列或列表中的任何对象。 然后,每个线程都可以使用get方法来访问此基础列表/队列,以便您可以从其他位置访问它们。 总而言之,线程做了一些工作,将一个对象放入队列中,其他对象可以访问该队列并从中获取一些东西。

答案 4 :(得分:0)

从主Executor类中实例化Queue,并通过构造函数或setter将其传递给Thread / Runnable。

然后,它可以使用此队列将对象或消息发送回主执行程序。

这是消息传递或actor模型的基本原则。

如果您正在使用Java 8,您还可以考虑使用流。

答案 5 :(得分:0)

你不能使用通知/听众模式吗?你可以给线程一个对象,当线程需要通知时,它应该回调。

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"
    }

}

你只是这样做:

MyRunnableListener listener = new MyRunnableListener();

MyRunnable myRunnable = MyRunnable(listener );

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