2015-11-18 38 views
0

我写了一个简单的聊天服务器,但我不知道如何将消息发送到另一个线程。我已经试过返回一个错误:从java中的另一个线程调用方法

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 

class ConnectorService extends Thread { 

    Socket connection; 
    ObjectInputStream in; 
    ObjectOutputStream out; 
    Thread _t; 

    public ConnectorService(Socket sock, ObjectInputStream _in, ObjectOutputStream _out) { 
     this.connection = sock; 
     try { 
      in = _in; 
      out = _out; 
     out.flush(); 
    } 
    catch(Exception e) { 
     System.err.println("Wystapil blad laczenia do socketu.."); 
    }  
} 

@Override 
public void run() { 

    this.send("Siemka :P"); 

    while(true) {   
     try { 
      String mess = (String)in.readObject();  

      String[] m = mess.split(":"); 

      if(m.length > 1) { 
       Thread _tmp; 
       if((_tmp = getThreadByName(m[ 0 ])) != null) { 
        // Here i've got an exception 
        ((ConnectorService) _tmp).send(m[ 1 ]); 
       } 
      } 
      else { 
       System.err.println("Zbyt malo argumentow.."); 
      } 

      this.getThreadByName("test"); 
      System.out.println("Klient: " + mess); 
      this.send(mess); 
     } 
     catch(ClassNotFoundException e) { 
      System.err.println("Bledny typ wiadomosci.."); 
     } 
     catch (IOException e) { 
     // e.printStackTrace(); 
      System.err.println("Polaczenie przerwane.."); 
      break; 
     } 
    } 


} 

public void start() { 
    System.out.println("Uruchamiam klienta"); 
    if(_t == null) { 
     _t = new Thread(this); 
     _t.start(); 
    } 
} 

public void send(String message) { 
    try { 
     out.writeObject(message); 
     out.flush(); 
    } 
    catch(IOException e) { 
     e.printStackTrace(); 
    } 
} 

public Thread getThreadByName(String threadName) { 
    for (Thread t : ConnectorService.getAllStackTraces().keySet()) { 
     if (t.getName().equals(threadName)) return t; 
     //System.out.println(t.getName()); 
    } 
    return null; 
} 

} 

我试着投一个线程,我从法getThreadByName()得到的,但后来我收到了,我不能投一个线程异常..

是否有可能在另一个线程中调用该方法? Greetings

+0

你在考虑如何完成工作的线程方面的工作。这真的不是一个好主意。你不需要发送消息给线程,你需要做一些特殊的事情,没有什么特别的理由你应该关心它是什么线程。 –

回答

2

像阿尔玛说,使用消息队列会更好,但因为使用的是本作一个简单的程序,这里有一个简单的解决方案:

你需要保持引用列表每个线程你做,还能使每个线程的名字,也许使用地图:

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 
import java.util.HashMap; 
import java.util.Map; 

class ConnectorService extends Thread { 

    static Map<String, Thread> connectorServices = new HashMap<>(); 

    Socket connection; 
    ObjectInputStream in; 
    ObjectOutputStream out; 
    Thread _t; 

    public ConnectorService(String name, Socket sock, ObjectInputStream _in, ObjectOutputStream _out) { 
     this.connection = sock; 
     try { 
      in = _in; 
      out = _out; 
      out.flush(); 
     } catch (Exception e) { 
      System.err.println("Wystapil blad laczenia do socketu.."); 
     } 
     // add this to the list of references to the threads 
     ConnectorService.connectorServices.put(name, this); 
    } 

    @Override 
    public void run() { 

     this.send("Siemka :P"); 

     while (true) { 
      try { 
       String mess = (String) in.readObject(); 

       String[] m = mess.split(":"); 

       if (m.length > 1) { 
        Thread _tmp; 
        if ((_tmp = getThreadByName(m[0])) != null) { 
         // Here i've got an exception 
         ((ConnectorService) _tmp).send(m[1]); 
        } 
       } else { 
        System.err.println("Zbyt malo argumentow.."); 
       } 

       this.getThreadByName("test"); 
       System.out.println("Klient: " + mess); 
       this.send(mess); 
      } catch (ClassNotFoundException e) { 
       System.err.println("Bledny typ wiadomosci.."); 
      } catch (IOException e) { 
       // e.printStackTrace(); 
       System.err.println("Polaczenie przerwane.."); 
       break; 
      } 
     } 

    } 

    public void start() { 
     System.out.println("Uruchamiam klienta"); 
     if (_t == null) { 
      _t = new Thread(this); 
      _t.start(); 
     } 
    } 

    public void send(String message) { 
     try { 
      out.writeObject(message); 
      out.flush(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public Thread getThreadByName(String threadName) { 
     return ConnectorService.connectorServices.get(threadName); 
    } 
} 

此代码应编译,做工精细...

但是请注意,我没怎么使用适当封装 - 我会离开那个你做...

2

有一大堆知识称为并发编程,看起来你必须从一开始就学习它。

你试图做的是等待/通知(谷歌了)。您在同步块中的一个线程中等待对象,然后其他线程调用通知相同的对象并且该线程唤醒。你可以把消息放在那个对象中来有效地传递它。

但这是做并发编程的基本方法。你真正想要的是一种并发队列。在一个线程中发出阻塞读取,将消息写入另一个线程的队列中 - 第一个线程将解除阻塞并获取消息。 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html

相关问题