concurrency: AtomicBoolean and volatile boolean

when multiple threads may be involved
AtomicBoolean: at least once code location tests and then sets the value
volatile boolean: test and set are in different code path
This commit is contained in:
Thomas Kuehne
2025-07-03 10:17:33 +02:00
committed by José Rebelo
parent b610f7720f
commit 8820f64d69
3 changed files with 12 additions and 11 deletions
@@ -31,6 +31,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
@@ -62,20 +63,21 @@ public final class GBScanEventProcessor implements Runnable {
private boolean discoverUnsupported = false;
private volatile boolean running = false;
private final AtomicBoolean running;
private Thread thread = null;
private final Callback callback;
public GBScanEventProcessor(final Callback callback) {
this.callback = callback;
running = new AtomicBoolean(false);
}
@Override
public void run() {
LOG.info("Device Found Processor Thread started.");
while (running) {
while (running.get()) {
try {
LOG.debug("Polling found devices queue, current size = {}", eventsToProcessQueue.size());
final String candidateAddress = eventsToProcessQueue.take();
@@ -93,12 +95,11 @@ public final class GBScanEventProcessor implements Runnable {
}
public void start() {
if (running) {
if (running.getAndSet(true)) {
LOG.warn("Already running!");
return;
}
running = true;
thread = new Thread("GBScanEventProcessor_" + THREAD_COUNTER.getAndIncrement()) {
@Override
public void run() {
@@ -109,7 +110,7 @@ public final class GBScanEventProcessor implements Runnable {
}
public void stop() {
running = false;
running.set(false);
if (thread != null) {
thread.interrupt();
@@ -35,6 +35,7 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
@@ -54,7 +55,7 @@ public final class BtBRQueue {
private final SocketCallback mCallback;
private final UUID mService;
private volatile boolean mDisposed;
private final AtomicBoolean mDisposed;
private final Context mContext;
private final int mBufferSize;
@@ -70,7 +71,7 @@ public final class BtBRQueue {
LOG.debug("Read thread started, entering loop");
while (!mDisposed) {
while (!mDisposed.get()) {
try {
if (mBtSocket == null)
throw new IOException("mBtSocket was null");
@@ -107,6 +108,7 @@ public final class BtBRQueue {
mCallback = socketCallback;
mService = supportedService;
mBufferSize = bufferSize;
mDisposed = new AtomicBoolean(false);
mWriteHandlerThread.start();
@@ -272,11 +274,10 @@ public final class BtBRQueue {
}
public void dispose() {
if (mDisposed) {
if (mDisposed.getAndSet(true)) {
return;
}
mDisposed = true;
disconnect();
if (readThread != null && readThread.isAlive()) {
@@ -33,7 +33,6 @@ import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
@@ -51,7 +50,7 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
private BluetoothSocket mBtSocket = null;
private InputStream mInStream = null;
private OutputStream mOutStream = null;
private boolean mQuit = false;
private volatile boolean mQuit = false;
@Override
public void quit() {