thread-limit logic, finetuning

This commit is contained in:
Arndt Brenschede 2020-02-06 08:29:18 +01:00
parent d7e759e93e
commit 4caea5f583

View file

@ -48,6 +48,8 @@ public class RouteServer extends Thread
private RoutingEngine cr = null; private RoutingEngine cr = null;
private volatile boolean terminated; private volatile boolean terminated;
private static Object threadPoolSync = new Object();
public void stopRouter() public void stopRouter()
{ {
RoutingEngine e = cr; RoutingEngine e = cr;
@ -271,9 +273,9 @@ public class RouteServer extends Thread
if ( bw != null ) try { bw.close(); } catch( Exception e ) {} if ( bw != null ) try { bw.close(); } catch( Exception e ) {}
if ( clientSocket != null ) try { clientSocket.close(); } catch( Exception e ) {} if ( clientSocket != null ) try { clientSocket.close(); } catch( Exception e ) {}
terminated = true; terminated = true;
synchronized( this ) synchronized( threadPoolSync )
{ {
notifyAll(); threadPoolSync.notifyAll();
} }
} }
} }
@ -323,34 +325,25 @@ public class RouteServer extends Thread
server.serviceContext = serviceContext; server.serviceContext = serviceContext;
server.clientSocket = clientSocket; server.clientSocket = clientSocket;
// cleanup thread list // kill an old thread if thread limit reached
for(;;)
{ cleanupThreadList( threadMap );
boolean removedItem = false;
for (Map.Entry<Long,RouteServer> e : threadMap.entrySet())
{
if ( e.getValue().terminated )
{
threadMap.remove( e.getKey() );
removedItem = true;
break;
}
}
if ( !removedItem ) break;
}
// kill thread if limit reached
if ( threadMap.size() >= maxthreads ) if ( threadMap.size() >= maxthreads )
{ {
Long k = threadMap.firstKey(); synchronized( threadPoolSync )
RouteServer victim = threadMap.get( k );
threadMap.remove( k );
if ( !victim.terminated )
{ {
synchronized( victim ) // wait up to 2000ms (maybe notified earlier)
{ // to prevent killing short-running threads
victim.wait( 1000 ); threadPoolSync.wait( 2000 );
} }
cleanupThreadList( threadMap );
if ( threadMap.size() >= maxthreads )
{
// no way... stop the oldest thread
Long k = threadMap.firstKey();
RouteServer victim = threadMap.get( k );
threadMap.remove( k );
victim.stopRouter(); victim.stopRouter();
} }
} }
@ -429,4 +422,25 @@ public class RouteServer extends Thread
} }
bw.write( "\n" ); bw.write( "\n" );
} }
private static void cleanupThreadList( TreeMap<Long, RouteServer> threadMap )
{
for ( ;; )
{
boolean removedItem = false;
for ( Map.Entry<Long, RouteServer> e : threadMap.entrySet() )
{
if ( e.getValue().terminated )
{
threadMap.remove( e.getKey() );
removedItem = true;
break;
}
}
if ( !removedItem )
{
break;
}
}
}
} }