2014-02-28 86 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