У меня есть одна 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 });
}
Теперь у меня есть другой поток, который читает некоторые данные из сокета и решает, какой поток должен проснуться, основываясь на уникальном идентификаторе потока.
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
Также существует другое странное поведение, которое может быть связано с этим.
Есть также ситуации, когда 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);