【问题标题】:Use of thread in Java class without implementing Runnable nor extending Thread在 Java 类中使用线程而不实现 Runnable 或扩展 Thread
【发布时间】: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


【解决方案1】:

这段代码 sn-p 可以帮助你:

public class SipJob implements Runnable {

    private SipProvider sipProvider;

    public SipJob(SipProvider sipProvider) {
                  // pass other parameters, if you need
        this.sipProvider=sipProvider;
    }

    @Override
    public void run() {
        // do the code, use SipProvider

    }
}

这将包含您要运行的代码。您可以根据需要向构造函数添加任意数量的参数,您可以从业务逻辑中使用它们。我建议不要传递资源(例如套接字),因为它们必须关闭,并且将打开和关闭代码分开是不明智的(必须由同一实体负责)。

现在你需要一个Thread 来执行:

SipProvider sipProvider = ...;
Runnable job = new SipJob(sipProvider);
Thread runner = new Thread(job);
runner.setDaemon(true);
runner.start();

请注意 - 据我了解 - 这将在后台运行,因此我设置了 setDaemon(true)

我不确定,但您可能在SipProvider 中有您想在线程中使用的内部内容。这种方式我建议首先扩展SipProvider类,允许访问那些内部变量/方法,使用SipJob类中的子类。

编辑:访问 SipProvider 内部的另一种方法是扩展类,并将 SipJob 类定义为后代中的inner class(不是内部静态类,而是实例类)。这样,您将自动访问包含 SipProvider 的实例变量——您甚至不必将其作为参数传递。从内部实例类试试这个:SipProvider.this.whateverField

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-16
    • 2016-11-09
    • 2014-06-02
    • 2018-01-10
    • 2011-01-22
    • 2012-02-15
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多