Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 停止网络接收器线程_Java_Android - Fatal编程技术网

Java 停止网络接收器线程

Java 停止网络接收器线程,java,android,Java,Android,假设我有一个类型为NetThread(定义如下)的对象,名为nt。我已经初始化并启动了它 nt = new NetThread(port, rs); nt.setDaemon(true); nt.setPriority(Thread.MAX_PRIORITY); nt.start(); 现在我希望能够在执行过程中的任何时候停止这个线程。我可以通过调用nt.interrupt()来实现这一点 然而,我想我会尝试做一些对我更有意义的事情:在NetThread中创建一个名为stopstend

假设我有一个类型为
NetThread
(定义如下)的对象,名为
nt
。我已经初始化并启动了它

nt = new NetThread(port, rs); 
nt.setDaemon(true); 
nt.setPriority(Thread.MAX_PRIORITY); 
nt.start(); 
现在我希望能够在执行过程中的任何时候停止这个线程。我可以通过调用
nt.interrupt()
来实现这一点

然而,我想我会尝试做一些对我更有意义的事情:在
NetThread
中创建一个名为
stopstending()
的方法

nt
运行时,我调用
nt.StopListening()
。没什么

线程一直在运行。我错过了什么?为什么这不起作用?

public class NetThread extends Thread {

    int port; 

    private static int PAYLOAD_MAX = 10000; 
    private static int NET_SO_TIMEOUT = 0; 
    private RunStats rs; 

    private boolean stopflag = false; 

    private StageCode stage; 

    NetThread(int port_number, RunStats runstats)
    {
        rs = runstats; 
        port = port_number; 
        stage = StageCode.STAGE_WAIT; 
    }

    public synchronized void stopListening()
    {
        Log.d(C.DTAG, "stopListening() was called..."); 
        stopflag=true; 
    }

    @Override
    public void run() 
    {
        receiveData(); 
        Log.d(C.DTAG, "Network thread is finished."); 
    }

    public void receiveData()
    {
        // request permission to do network operations in manifest file...done

        Log.d(C.DTAG, "network thread has started."); 

        // start the network side of things
        DatagramSocket sock = null; 
        DatagramPacket pkt = null; 

        try 
        {
            byte[] data = new byte[PAYLOAD_MAX]; 
            sock = new DatagramSocket(port); 
            sock.setSoTimeout(NET_SO_TIMEOUT);
            pkt = new DatagramPacket(data, 0, PAYLOAD_MAX); 

            while (!stopflag)
            {
                Thread.sleep(0); // allow for an interrupt
                try 
                {
                    sock.receive(pkt); 
                    int length = pkt.getLength(); 
                    processPayload(pkt.getData(), length); 
                }
                catch (InterruptedIOException e)
                {
                    // thrown when a timeout occurs
                    Log.d(C.DTAG, "net: no packets yet"); 
                }
            }
            Log.d(C.DTAG, "done receiving."); 
            if (sock != null) sock.close(); 
        } 
        catch (InterruptedException x) 
        {
            Log.d(C.DTAG, "net: was interrupted."); 
        } 
        catch (SocketException e) 
        {
            Log.d(C.DTAG, "net: SocketException"); 
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            Log.d(C.DTAG, "net: IOException"); 
            e.printStackTrace();
        }
        if (sock != null) sock.close(); 
    }

    public void processPayload(byte[] data, int length)
    {
        if (length < 20) return; 

        int sc =    data[ 0] & 0x000000FF | data[ 1]<<8 & 0x0000FF00 | data[ 2]<<16 & 0x00FF0000 | data[ 3]<<24 & 0xFF000000; 
        int seq =   data[ 4] & 0x000000FF | data[ 5]<<8 & 0x0000FF00 | data[ 6]<<16 & 0x00FF0000 | data[ 7]<<24 & 0xFF000000; 
        int i =     data[ 8] & 0x000000FF | data[ 9]<<8 & 0x0000FF00 | data[10]<<16 & 0x00FF0000 | data[11]<<24 & 0xFF000000; 
        int s =     data[12] & 0x000000FF | data[13]<<8 & 0x0000FF00 | data[14]<<16 & 0x00FF0000 | data[15]<<24 & 0xFF000000; 
        int n =     data[16] & 0x000000FF | data[17]<<8 & 0x0000FF00 | data[18]<<16 & 0x00FF0000 | data[19]<<24 & 0xFF000000; 

        StageCode sc2 = null; 
        switch (sc)
        {
        case 20: sc2 = StageCode.STAGE_INIT; break; 
        case 30: sc2 = StageCode.STAGE_TEST; break; 
        case 40: sc2 = StageCode.STAGE_STOP; break; 
        }

        TestPacketHeader tph = new TestPacketHeader(sc2, seq, i, s, n); 
        rs.RegisterReceivedPacket(tph); 

        if (sc2 == StageCode.STAGE_STOP) stopflag = true; 
    }

    public synchronized StageCode status()
    {
        return stage; 
    }
}
公共类NetThread扩展线程{
国际港口;
专用静态int有效载荷_MAX=10000;
私有静态int NET_SO_TIMEOUT=0;
私人跑步者;
私有布尔stopflag=false;
私人舞台表演;
NetThread(int端口号,RunStats RunStats)
{
rs=runstats;
端口=端口号;
stage=StageCode.stage\u WAIT;
}
公共同步的void stopListening()
{
Log.d(C.DTAG,“stopListening()被调用…”);
stopflag=true;
}
@凌驾
公开募捐
{
接收数据();
Log.d(C.DTAG,“网络线程已完成”);
}
public void receiveData()
{
//请求在清单文件中执行网络操作的权限…完成
Log.d(C.DTAG,“网络线程已启动”);
//启动网络方面的事情
DatagramSocket sock=null;
DatagramPacket pkt=null;
尝试
{
字节[]数据=新字节[PAYLOAD_MAX];
sock=新的DatagramSocket(端口);
设置超时(净超时);
pkt=新数据包(数据,0,有效载荷最大值);
而(!stopflag)
{
Thread.sleep(0);//允许中断
尝试
{
短袜接收(pkt);
int length=pkt.getLength();
processPayload(pkt.getData(),长度);
}
捕获(中断异常e)
{
//发生超时时引发
Log.d(C.DTAG,“网络:还没有数据包”);
}
}
Log.d(C.DTAG,“完成接收”);
如果(sock!=null)sock.close();
} 
捕捉(中断异常x)
{
Log.d(C.DTAG,“网络:被中断”);
} 
捕获(SocketException e)
{
Log.d(C.DTAG,“net:SocketException”);
e、 printStackTrace();
} 
捕获(IOE异常)
{
Log.d(C.DTAG,“net:IOException”);
e、 printStackTrace();
}
如果(sock!=null)sock.close();
}
public void processPayload(字节[]数据,整数长度)
{
如果(长度<20)返回;

int sc=data[0]&0x000000FF|data[1]您尝试这样做的方式本质上是重新创建中断在幕后的作用,因此您可能最好只使用中断。前面已经说过,如果您使布尔值
易失性
,那么线程将看到其他线程所做的更改,那么您的代码应该可以工作。:)

中断的另一个优点是,如果线程处于某些等待状态,它会唤醒线程,因此会导致中断处理速度加快。请注意,这不能完全依赖于中断,因为在检查标志和进入等待状态之间可能会收到中断,在这种情况下,仍需要等待在看到国旗之前把我赶出去


中断和您自己版本的中断都是通过向线程发出停止信号,然后让线程自动关闭来工作的。这是正确的做法,因为积极地杀死线程可能会导致各种恶劣的副作用,例如半完成的处理。

您能不能也说一下,为什么它更好在(!isInterrupted())
时始终使用
,并调用
myThread.interrupt();
。它工作得很好。事实上,你是对的,我正在考虑一种异步终止,这不是中断所做的。竖起大拇指。另外,我想说我喜欢使用
Thread.interrupt()
因为它唤醒了线程。我经常遇到这样的情况(在我看来)更好的行为。是的,我只是想我应该提到MalaKa,我也提到了它的主要局限性。好吧,Tim的易变提示解决了一半问题。另一半问题解决了,因为我意识到NET_so_TIMEOUT=0意味着循环永远挂在接收数据包的线路上。我将NET_so_TIMEOUT=500,然后n在我调用stopListening()的500毫秒内,执行将实际达到循环条件(!stopflag)。Duh。谢谢大家