【问题标题】:How to fire event listener from Java thread如何从 Java 线程触发事件侦听器
【发布时间】:2014-04-01 17:21:13
【问题描述】:

我有里面有 Socket 的线程。当 soket 接收到一些数据时,我需要触发事件(使用我的子类 EventObject)。事件侦听器是从主线程添加的(到某个列表?)。这样可以吗?

Pseudocode:



public class SocketThread extends Thread{
    private Socket socket;
    private MyEventListener eventListener;

    public SocketThread(Socket socket, MyEventListener eventListener) {
        this.socket=socket;
        this.eventListener=eventListener;
    }

   public void run() {
        get socket input stream...
        get socket output stream...
        when data received, call process(data) 
    }

   void process(data){
     synchronized(this){
        myEvent event=new MyEvent(data);
        eventListener.fireSomeEvent(myEvent );
    }
}


// main thread

ServerSocket serverSocket=new ServerSocket(host,port);
Socket socket= serverSocket.accept();
ClientThread cthr = new SocketThread (sckt,new MyEventListener(){ 
    void fireSomeEvent(MyEvent event){
    //some code
    }
});

【问题讨论】:

  • 我认为您的解决方案通常没问题,但我认为您可能会从实施producer-consumer pattern 中受益。您的套接字线程产生的消息被添加到阻塞队列中,只要有新消息/数据可用,另一个类(您目前拥有的事件侦听器)就会从中获取。
  • 我应该删除同步块吗?
  • 是的,如果您使用生产者-消费者模式并且使用阻塞队列,则不需要像 the blocking queue's add / take methods are thread safe 那样的同步块。

标签: java multithreading sockets


【解决方案1】:

这似乎很好。只要您不更改eventListener,就不会出现并发问题。但请注意,fireSomeEvent() 将从SocketThread 运行。如果你在那里做的事情不是线程安全的,你可能(将会)遇到问题。所以这就是你需要某种同步的地方。

【讨论】:

  • 我知道事件将从 SocketThread 中触发。如果触发事件正在访问某个主线程的数据,如何从触发事件中锁定该数据?我已经从同步块中触发了该事件(我应该删除它吗?)
  • 该同步块仅适用于不从一个套接字同时触发多个事件(如果您的 run 方法在没有任何新线程的情况下触发它们,则无论如何都不应该发生这种情况)。我认为您正在寻找的是在主对象上同步(注意:对象,而不是线程)。
  • 但是对于触发多个事件,使用一些列表,这些事件被添加在同一个线程(主)中,在 for 循环中是好的?
猜你喜欢
  • 2020-09-06
  • 1970-01-01
  • 2015-12-18
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-14
  • 1970-01-01
相关资源
最近更新 更多