【发布时间】:2013-01-11 12:59:28
【问题描述】:
我正在编写一个可以接收和发送数据报包的类 SipProvider。此类是我正在处理的 SIP 堆栈的一部分。
我提供的 API 不会使 SipProvider 实现 Runnable 或 Extend Thread。
我尝试实现的解决方案是在 SipProvider 中创建一个新类,该类将扩展线程。我想为线程提供参数并且我有编译问题(没有可访问类型 SipProvider 的封闭实例),线程无法实例化,因为它与 SipProvider 相关(我发现它应该是静态的但不知道怎么做)。
我在 Internet 上查找了如何在类中实现线程,但没有找到解决方案。有没有已知的方法来做到这一点。
这是我一直在尝试做的事情的快照。这只是课堂的一部分。
public class SipProvider {
//startOn is the method which allow the user to listen on a port
//so the user don't have to bother creating a thread and so on
public static SipProvider startOn(listeningPoint) {
SipProvider sipProvider = new SipProvider();
thread.sipProvider = sipProvider;
thread.run();
return sipProvider;
}
//this is the thread i want to handle the listening process
public class ReceiveThread extends Thread{
public SipProvider sipProvider;
public ReceiveThread(SipProvider sipProvider){
this.sipProvider = sipProvider;
}
@Override
public void run(){
try {
int MAX_LEN = 200;
DatagramSocket datagramSocket = new DatagramSocket(
listeningPoint.getPort());
sipProvider.datagramSocket = datagramSocket;
byte[] buffer = new byte[MAX_LEN];
DatagramPacket packet = new DatagramPacket(buffer, MAX_LEN);
while (!datagramSocket.isClosed()) {
sipProvider.setSipListener(sipListener);
datagramSocket.receive(packet);
//handle packet content
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
艾迪丝:
除了提议的解决方案(效果很好)之外,我发现的另一个解决方案是实例化一个新线程并同时定义它的 run() 方法。我的示例中的 startOn 方法开始在 listenerPoint 上进行侦听(其中包含有关端口地址和使用的协议的信息)。
public static SipProvider startOn(final ListeningPoint listeningPoint) throws SocketException {
final SipProvider sipProvider = new SipProvider(listeningPoint);
new Thread() {
@Override
public void run() {
try {
while (true) {
DatagramPacket packet = newDatagramPacket(new byte[200], 200);
sipProvider.datagramSocket.receive(packet);
String content = new String(packet.getData(), 0, packet.getLength());
sipProvider.sipListener.processContent(content);
}
} catch (Exception e) {
}
}
}.start();
return sipProvider;
}
【问题讨论】:
-
尝试:新的 SipProvider().new ReceiveThread()
-
问题是我想将对象 sipProvider 传递给线程(因为 sipProvider 包含有关要监听的端口和地址的信息)。写:new SipProvider().new ReceiveThread(sipProvider) 是否有意义?
-
我认为是的。 “new SipProvider()”部分只是一个满足编译器的虚拟实例——“没有 SipProvider 类型的封闭实例是可访问的”——这意味着我需要一个 SipProvider 实例来实例化 ReceiveThread。如果你把你的 ReceiveThread 放在它自己的文件中,你就可以像往常一样实例化它
-
好的,我会尝试这种方式。感谢您的回复。
-
其实如果把ReceiveThread(或者SipJob)和实例类(不是静态类)放在同一个类中,就不需要实例化SipProvider,因为内部类会被绑定到 SipProvider 的一个实例。因此,您将可以立即访问 SipProvider 的所有方法和属性。
标签: multithreading runnable datagram