이라고하는 유형이 NetThread
(아래 정의 됨) 인 것으로 가정합니다. 초기화하고 시작했습니다.네트워크 수신자 스레드 중지
nt = new NetThread(port, rs);
nt.setDaemon(true);
nt.setPriority(Thread.MAX_PRIORITY);
nt.start();
이제 실행 중에 언제든지이 스레드를 중지하고 싶습니다. nt.interrupt()
에 전화하여이 작업을 수행 할 수 있습니다.
그러나 나는 내게 더 의미있는 것을하려고 노력할 것이라고 생각했다 : 이라고하는 NetThread
내에 메소드를 작성하십시오.
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;
}
}
왜 더 나은지 말할 수 있습니까? 나는 항상 while (! isInterrupted())를 사용하고'myThread.interrupt();'를 호출한다. 그것은 단지 잘 작동합니다. – MalaKa
사실 당신 말이 맞습니다. 저는 인터럽트가 아닌 비동기식 킬을 생각하고있었습니다. –
내 대답을 편집했습니다. –