gpt4 book ai didi

java - 停止网络接收器线程

转载 作者:行者123 更新时间:2023-12-01 13:41:38 24 4
gpt4 key购买 nike

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

nt = new NetThread(port, rs); 
nt.setDaemon(true);
nt.setPriority(Thread.MAX_PRIORITY);
nt.start();

现在我希望能够在执行期间的任何时候停止该线程。我可以通过调用 nt.interrupt() 来完成此操作。

但是,我想尝试做一些对我来说更有意义的事情:在 NetThread 中创建一个名为 StopListening() 的方法。

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;
}
}

最佳答案

您尝试执行此操作的方式本质上是重新创建中断在幕后所做的事情,因此您可能最好只使用中断。话虽如此,如果您将 boolean 值设置为 volatile ,那么线程将看到其他线程的更改,从而使您的代码应该可以工作。 :)

中断还有一个优点,如果线程处于某些等待状态,它会唤醒线程,因此往往会导致中断处理得更快。请注意,这不能完全依赖,因为在检查标志和进入等待状态之间可能会收到中断 - 在这种情况下,在看到标志之前等待仍然需要超时。

中断和您自己的中断版本都通过向线程发出信号表明它应该停止然后让线程自行关闭来工作。这是正确的做法,因为仅仅积极地终止线程可能会导致各种令人讨厌的副作用,例如半完成的处理。

关于java - 停止网络接收器线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20707052/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com