3131import java .util .concurrent .BlockingQueue ;
3232import java .util .concurrent .TimeUnit ;
3333import java .util .concurrent .atomic .AtomicBoolean ;
34+ import java .util .concurrent .atomic .AtomicInteger ;
3435
3536import com .rabbitmq .client .AMQP ;
3637import com .rabbitmq .client .impl .AMQCommand ;
@@ -388,7 +389,7 @@ public static class AsyncLogger implements Logger {
388389
389390 private final Runnable loggerRunnable ;
390391
391- private final AtomicBoolean started ;
392+ private final SafeCounter countStarted ;
392393 private volatile Thread loggerThread = null ;
393394
394395 /**
@@ -430,7 +431,7 @@ public AsyncLogger(OutputStream os, int flushInterval) {
430431 throw new IllegalArgumentException ("Flush interval ("
431432 + flushInterval + "ms) must be positive and at least "
432433 + MIN_FLUSH_INTERVAL + "ms." );
433- this .started = new AtomicBoolean ( false );
434+ this .countStarted = new SafeCounter ( );
434435
435436 PrintStream printStream = new PrintStream (new BufferedOutputStream (
436437 os , BUFFER_SIZE ), false );
@@ -448,8 +449,17 @@ public void log(String message) {
448449 }
449450 }
450451
452+ public boolean start () {
453+ if (this .countStarted .testZeroAndIncrement ()) {
454+ this .loggerThread = new Thread (this .loggerRunnable );
455+ this .loggerThread .start ();
456+ return true ;
457+ }
458+ return false ; // meaning already started
459+ }
460+
451461 public boolean stop () {
452- if (this .started . compareAndSet ( true , false )) {
462+ if (this .countStarted . decrementAndTestZero ( )) {
453463 if (this .loggerThread != null ) {
454464 try {
455465 this .queue .put (new Pr <String , LogCmd >(null , LogCmd .STOP ));
@@ -464,16 +474,7 @@ public boolean stop() {
464474 return false ; // meaning already stopped
465475 }
466476
467- public boolean start () {
468- if (this .started .compareAndSet (false , true )) {
469- this .loggerThread = new Thread (this .loggerRunnable );
470- this .loggerThread .start ();
471- return true ;
472- }
473- return false ; // meaning already started
474- }
475-
476- private static class AsyncLoggerRunnable implements Runnable {
477+ private class AsyncLoggerRunnable implements Runnable {
477478 private final int flushInterval ;
478479 private final PrintStream ps ;
479480 private final BlockingQueue <Pr <String , LogCmd > > queue ;
@@ -515,6 +516,7 @@ public void run() {
515516 this .ps .flush ();
516517
517518 } catch (InterruptedException ie ) {
519+ AsyncLogger .this .countStarted .reset ();
518520 drainCurrentQueue ();
519521 this .ps .println ("Interrupted." );
520522 this .ps .flush ();
@@ -531,4 +533,31 @@ private void drainCurrentQueue() {
531533 }
532534 }
533535 }
536+
537+ private static class SafeCounter {
538+ private final Object countMonitor = new Object ();
539+ private int count ;
540+ public SafeCounter () {
541+ this .count = 0 ;
542+ }
543+ public boolean testZeroAndIncrement () {
544+ synchronized (this .countMonitor ) {
545+ int val = this .count ;
546+ this .count ++;
547+ return (val == 0 );
548+ }
549+ }
550+ public boolean decrementAndTestZero () {
551+ synchronized (this .countMonitor ) {
552+ if (this .count == 0 ) return false ;
553+ --this .count ;
554+ return (0 == this .count );
555+ }
556+ }
557+ public void reset () {
558+ synchronized (this .countMonitor ) {
559+ this .count = 0 ;
560+ }
561+ }
562+ }
534563}
0 commit comments