5

I write a thread class called T.

My purpose is to make sure only one thread object running at a time.

So when the thread object is called, it would check a boolean flag called BUSY.

My question is what is the different between

private static AtomicBoolean BUSY = new AtomicBoolean(false);

and

private static boolean BUSY = false;

I thought if using the 'static', all object would only check one BUSY boolean variable so that would make sure only one thread object is running.

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
Hexor
  • 525
  • 1
  • 8
  • 22

4 Answers4

8

You must at least make the boolean variable volatile and the AtomicBoolean variable final in order to have a comparable solution. After you do that, there will be no difference for your use case.

The difference comes about if you use AtomicBoolean's getAndSet or compareAndSet methods, which combine one read and one write action into an atomic whole, whereas these are not atomic when done against a volatile.

Pang
  • 9,564
  • 146
  • 81
  • 122
Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
2

You can use a boolean and with proper synchronization (and making volatile) can achieve what you need.
But by using the AtomicBoolean you can check the current value atomically without the need to write code for synchronization yourself

Cratylus
  • 52,998
  • 69
  • 209
  • 339
0

As said by others you must make the variables final / volatile respectively.

From what you describe I fear you have a place where you do something like this:

if (!BUSY){
    BUSY = true;
}

Note that this is broken in absence of commons synchronization, because two threads might check the flag, both seeing it as false and starting their work.

I suggest looking into the existing structures for handling concurrency: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html

Especially Semaphore with a single permit might be what you are looking for.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
0

A useful feature of an AtomicBoolean is to allow a single thread to continue if and only if BUSY is false but not to let any other threads to continue.

private static AtomicBoolean BUSY = new AtomicBoolean(false);

public void doWork(){
  if(BUSY.compareAndSet(false,true)){
     //do some work
     BUSY.set(false);
  }else{
     //some other thread won, return now or retry later?
  }
}

So here only one thread will doWork at any given time. You cannot achieve this with a volatile boolean because you cannot be sure that Thread.currentThread() set the boolean.

John Vint
  • 39,695
  • 7
  • 78
  • 108
  • I suggest to perform the `BUSY.set(false)` in a `finally` to be sure it actually gets done. – Harald Feb 16 '23 at 08:22