在线程上调用中断非常慢

时间:2019-10-28 15:35:45

标签: java multithreading sleep interrupt

我有一个ConcurrentHashMap,用于存储将一些数据发送到套接字并等待响应的线程。

public class MyThreadSocketAsync implements Runnable

在该线程中,我有:

// add to hashmap
SocketHandler.getInstance().addThread(this, Thread.currentThread());

// send data
this.sendData();
 log.info("goToSleep");

//go to sleep
try {
    Thread.sleep(5000);
} catch (Exception t) {
}
log.info ("Thread awaken");

我在SocketHandler中的位置:

public void addThread(MyThreadSocketAsync t, Thread thread) {
    String threadIdS = generateThreadKey(t.getThreadId());
    threadList.put(threadIdS, new Object[] { t, thread });
}

现在,我有另一个线程从套接字读取一些数据,并根据唯一的threadId决定应唤醒哪个线程。

public void releaseThread(String threadId, String returnValue) {
  Object[] o = threadList.remove(threadId);
  MyThreadSocketAsync t = o != null ? (MyThreadSocketAsync) o[0] : null;
  if (t != null) {
    t.setReturnValue(returnValue, threadId);
    ((Thread) o[1]).interrupt();
     log.info ("Awake thread");
  }
}

问题是两个日志之间的“唤醒线程”和“线程唤醒”之间的间隔时间超过了5-20秒。似乎在线程上执行中断时,它不会立即执行。现在重要的是,这有时会发生(特别是当我们在系统上执行多个并发线程时)。 问题是为什么有时中断不能立即起作用?

从生产服务器登录:

25.10.2019 13:29:30.207  [DEBUG]  163133 > logMemoryUsageInfo : Total memory used: 23877 KB, free memory:37562 KB, JVM threadCount:17
25.10.2019 13:29:30.207  [INFO ]  163133 > MyThreadSocketAsync.run : Message received, concurentThreads:5
25.10.2019 13:29:30.211  [INFO ]  163133 > MyThreadSocketAsync.handleMessage : length:40, hex:08008220000****
25.10.2019 13:29:30.211  [INFO ]  163133 > MyThreadSocketAsync.handleMessage : ECHO message received
25.10.2019 13:29:30.211  [INFO ]  163133 > SocketHandler.addThread : key=0000163133, threadList.size=8
25.10.2019 13:29:30.211  [INFO ]  163133 > SocketHandler.sendMessage : messageToSend=0000163133101****
25.10.2019 13:29:30.211  [DEBUG]  163133 > MyThreadSocketAsync.handleMessage : goToSleep
25.10.2019 13:29:30.258  [INFO ]  163133 > SocketHandler.releaseThread : Awake thread key=0000163133, threadList.size=12
25.10.2019 13:30:32.304  [DEBUG]  163133 > MyThreadSocketAsync.handleMessage : Thread Awaken=62093 msec
25.10.2019 13:30:32.305  [DEBUG]  163133 > MyThreadSocketAsync.handleMessage : Exit thread

还有另一种奇怪的行为,可能与此有关。

在某些情况下,线程会在20毫秒后唤醒,但不是使用我的interrupt()方法,而是其他(系统,GC,..)中断线程,所以在我的日志中,我只有:

25.10.2019 13:24:57.011  [DEBUG]  162448 > MyThreadSocketAsync.handleMessage : goToSleep
25.10.2019 13:24:57.026  [DEBUG]  162448 > MyThreadSocketAsync.handleMessage : Thread Awaken=15 msec

我不知道为什么有时会发生这种情况?

对于线程执行,我使用threadPool:

threadPool = new ThreadPoolExecutor(10, 500, 1800, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
...
MyThreadSocketAsync cc = new MyThreadSocketAsync(messageCount, receivedMessage);
threadPool.execute(cc);

0 个答案:

没有答案