我有一个在我的Web应用程序启动时启动的线程(contextInitialized)。所有这个线程都是,从套接字读取数据。
public void run() {
while (!Thread.currentThread().isInterrupted() || !this.isInterrupted()
|| !stopped) {
try {
System.out.println("************polling..............");
readData();
Thread.sleep(300);
} catch (InterruptedException e) {
System.out.println("interrupted... ");
Thread.currentThread().interrupt();
break; //required?
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void shutdown() {
stopped = true;
}
// I know I'm blocking here.
private void readData() {
if (null == socket)
throw new ConnectionException();
if (inStream == null) {
inStream = this.socket.getInputStream();
}
byte[] buff = new byte[length];
int receiveLength = 0;
do {
try {
receiveLength = inStream.read(buff, 0, length);
} catch (Exception e) {
e.printStackTrace();
}
} while (receiveLength <= 0);
}
我在contextDestroyed中调用了interrupt()方法,但这个线程无法停止,为什么呢?
if (poller != null) {
((Poller) poller).shutdown();
poller.interrupt();
// should I need to do this?
while (poller.isAlive()) {
;
}
}
答案 0 :(得分:0)
如果我这样做,我会用不同的库来做这件事:
真正的问题是readData
内的这个循环:
do {
try {
receiveLength = inStream.read(buff, 0, length);
} catch (Exception e) {
e.printStackTrace();
}
} while (receiveLength <= 0);
如果你在这里使用一个循环,它将继续读取,即使没有什么可读,而不是返回到具有延迟的外循环。摆脱循环。另外,将方法中的所有初始化移动到构造函数。
我将如何做到这一点:
class ConnectionReader implements TimerTask {
InputStream inStream;
byte[] buf;
public ConnectionReader(Socket socket, int length){
if (null == socket)
throw new ConnectionException();
if (inStream == null) {
inStream = this.socket.getInputStream();
}
buf = new byte[length]
}
@Override
public void run() {
try {
System.out.println("polling...");
readData();
} catch (InterruptedException e) {
System.out.println("interrupted...");
cancel()
} catch (Exception e) {
e.printStackTrace();
}
}
private void readData() {
try {
receiveLength = inStream.read(buff, 0, length);
} catch (Exception e) {
e.printStackTrace();
}
}
}
要启动它,请将Timer设置为所需的300ms延迟:
TimerTask readTask = new ConnectionReader(this.socket, length);
new Timer().schedule(readTask,0,300);
要取消它,只需拨打readTask.cancel()
。