2014-02-28 65 views
0

我有Socket内部的线程。当soket收到一些数据时,我需要触发事件(使用我的sublassed EventObject)。事件监听器是从主线程添加的(到某个列表?)。这个可以吗?如何从Java线程触发事件监听器

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

我认为你的解决方案通常是好的,但我想你可能会从实施[生产者 - 消费者模式](http://java.dzone.com/articles/producer-consumer-pattern)中受益。您的套接字线程会生成添加到阻塞队列中的消息,当有新消息/数据可用时,其他类(您当前拥有的事件侦听器)将从其中捕获该消息。 –

+0

我应该删除syncronization块吗? – Sanyin

+0

是的,如果您执行生产者 - 消费者模式并且使用阻塞队列,则不需要同步块[阻塞队列的add/take方法是线程安全的](http://stackoverflow.com/a/ 877472分之2695437)。 –

回答

0

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

+0

我知道事件将从SocketThread中被触发。如果事件正在访问一些主线程的数据,如何锁定来自触发事件的数据?我已经从同步块触发了该事件(我应该删除它吗?) – Sanyin

+0

该同步块仅适用于不从一个套接字同时触发多个事件(如果您的run方法在没有任何新线程的情况下触发它们,则不应发生这种情况) 。我认为你正在寻找的是同步主要对象(注:对象,而不是线程)。 – ddmps

+0

但是使用一些列表,在同一个线程(main),for循环内添加一些列表来触发几个事件会很好吗? – Sanyin