3131import java .util .WeakHashMap ;
3232import java .util .concurrent .ExecutorService ;
3333import java .util .concurrent .Executors ;
34+ import java .util .concurrent .LinkedBlockingQueue ;
3435import java .util .concurrent .Semaphore ;
36+ import java .util .concurrent .ThreadFactory ;
37+ import java .util .concurrent .ThreadPoolExecutor ;
38+ import java .util .concurrent .TimeUnit ;
39+ import java .util .concurrent .atomic .AtomicInteger ;
3540
3641public class AsyncServer {
3742 public static final String LOGTAG = "NIO" ;
@@ -85,7 +90,7 @@ public static void post(Handler handler, Runnable runnable) {
8590 catch (Throwable ex ) {
8691 }
8792 }
88-
93+
8994 static AsyncServer mInstance = new AsyncServer ();
9095 public static AsyncServer getDefault () {
9196 return mInstance ;
@@ -114,7 +119,7 @@ private void handleSocket(final AsyncNetworkSocket handler) throws ClosedChannel
114119 ckey .attach (handler );
115120 handler .setup (this , ckey );
116121 }
117-
122+
118123 public void removeAllCallbacks (Object scheduled ) {
119124 synchronized (this ) {
120125 mQueue .remove (scheduled );
@@ -134,7 +139,7 @@ public void run() {
134139 }
135140 });
136141 }
137-
142+
138143 public Object postDelayed (Runnable runnable , long delay ) {
139144 Scheduled s ;
140145 synchronized (this ) {
@@ -161,11 +166,11 @@ public Object postDelayed(Runnable runnable, long delay) {
161166 }
162167 return s ;
163168 }
164-
169+
165170 public Object post (Runnable runnable ) {
166171 return postDelayed (runnable , 0 );
167172 }
168-
173+
169174 public Object post (final CompletedCallback callback , final Exception e ) {
170175 return post (new Runnable () {
171176 @ Override
@@ -174,7 +179,7 @@ public void run() {
174179 }
175180 });
176181 }
177-
182+
178183 public void run (final Runnable runnable ) {
179184 if (Thread .currentThread () == mAffinity ) {
180185 post (runnable );
@@ -263,7 +268,7 @@ public void run() {
263268 catch (Exception e ) {
264269 }
265270 }
266-
271+
267272 protected void onDataReceived (int transmitted ) {
268273 }
269274
@@ -335,7 +340,7 @@ protected void cancelCleanup() {
335340 SocketChannel socket ;
336341 ConnectCallback callback ;
337342 }
338-
343+
339344 private ConnectFuture connectResolvedInetSocketAddress (final InetSocketAddress address , final ConnectCallback callback ) {
340345 final ConnectFuture cancel = new ConnectFuture ();
341346 assert !address .isUnresolved ();
@@ -396,7 +401,14 @@ public Cancellable connectSocket(final String host, final int port, final Connec
396401 return connectSocket (InetSocketAddress .createUnresolved (host , port ), callback );
397402 }
398403
399- private static ExecutorService synchronousWorkers = Executors .newFixedThreadPool (4 );
404+ private static ExecutorService newSynchronousWorkers () {
405+ ThreadFactory tf = new NamedThreadFactory ("AsyncServer-worker-" );
406+ ThreadPoolExecutor tpe = new ThreadPoolExecutor (1 , 4 , 10L ,
407+ TimeUnit .SECONDS , new LinkedBlockingQueue <Runnable >(), tf );
408+ return tpe ;
409+ }
410+
411+ private static ExecutorService synchronousWorkers = newSynchronousWorkers ();
400412 public Future <InetAddress []> getAllByName (final String host ) {
401413 final SimpleFuture <InetAddress []> ret = new SimpleFuture <InetAddress []>();
402414 synchronousWorkers .execute (new Runnable () {
@@ -487,7 +499,7 @@ public void run() {
487499 });
488500 return handler ;
489501 }
490-
502+
491503 public AsyncDatagramSocket connectDatagram (final SocketAddress remote ) throws IOException {
492504 final DatagramChannel socket = DatagramChannel .open ();
493505 final AsyncDatagramSocket handler = new AsyncDatagramSocket ();
@@ -509,7 +521,7 @@ public void run() {
509521 });
510522 return handler ;
511523 }
512-
524+
513525 final static WeakHashMap <Thread , AsyncServer > mServers = new WeakHashMap <Thread , AsyncServer >();
514526
515527 private boolean addMe () {
@@ -527,7 +539,7 @@ private boolean addMe() {
527539 public static AsyncServer getCurrentThreadServer () {
528540 return mServers .get (Thread .currentThread ());
529541 }
530-
542+
531543 Thread mAffinity ;
532544 private void run (boolean newThread ) {
533545 final SelectorWrapper selector ;
@@ -596,10 +608,10 @@ public void run() {
596608 }
597609 return ;
598610 }
599-
611+
600612 run (this , selector , queue );
601613 }
602-
614+
603615 private static void run (final AsyncServer server , final SelectorWrapper selector , final PriorityQueue <Scheduled > queue ) {
604616// Log.i(LOGTAG, "****AsyncServer is starting.****");
605617 // at this point, this local queue and selector are owned
@@ -666,11 +678,11 @@ private static void shutdownEverything(SelectorWrapper selector) {
666678 catch (Exception e ) {
667679 }
668680 }
669-
681+
670682 private static final long QUEUE_EMPTY = Long .MAX_VALUE ;
671683 private static long lockAndRunQueue (final AsyncServer server , final PriorityQueue <Scheduled > queue ) {
672684 long wait = QUEUE_EMPTY ;
673-
685+
674686 // find the first item we can actually run
675687 while (true ) {
676688 Scheduled run = null ;
@@ -689,10 +701,10 @@ private static long lockAndRunQueue(final AsyncServer server, final PriorityQueu
689701 }
690702 }
691703 }
692-
704+
693705 if (run == null )
694706 break ;
695-
707+
696708 run .runnable .run ();
697709 }
698710
@@ -834,11 +846,11 @@ public void run() {
834846 }
835847 });
836848 }
837-
849+
838850 public Thread getAffinity () {
839851 return mAffinity ;
840852 }
841-
853+
842854 public boolean isAffinityThread () {
843855 return mAffinity == Thread .currentThread ();
844856 }
@@ -847,4 +859,27 @@ public boolean isAffinityThreadOrStopped() {
847859 Thread affinity = mAffinity ;
848860 return affinity == null || affinity == Thread .currentThread ();
849861 }
862+
863+ private static class NamedThreadFactory implements ThreadFactory {
864+ private final ThreadGroup group ;
865+ private final AtomicInteger threadNumber = new AtomicInteger (1 );
866+ private final String namePrefix ;
867+
868+ NamedThreadFactory (String namePrefix ) {
869+ SecurityManager s = System .getSecurityManager ();
870+ group = (s != null ) ? s .getThreadGroup () :
871+ Thread .currentThread ().getThreadGroup ();
872+ this .namePrefix = namePrefix ;
873+ }
874+
875+ public Thread newThread (Runnable r ) {
876+ Thread t = new Thread (group , r ,
877+ namePrefix + threadNumber .getAndIncrement (), 0 );
878+ if (t .isDaemon ()) t .setDaemon (false );
879+ if (t .getPriority () != Thread .NORM_PRIORITY ) {
880+ t .setPriority (Thread .NORM_PRIORITY );
881+ }
882+ return t ;
883+ }
884+ }
850885}
0 commit comments