Can I use Collection.size () to replace the counter in this code?

Here is the code:

public class LogService { private final BlockingQueue<String> queue; private final LoggerThread loggerThread; private final PrintWriter writer; @GuardedBy("this") private boolean isShutdown; @GuardedBy("this") private int reservations; // <-- counter public void start() { loggerThread.start(); } public void stop() { synchronized (this) { isShutdown = true; } loggerThread.interrupt(); } public void log(String msg) throws InterruptedException { synchronized (this) { if (isShutdown) throw new IllegalStateException(...); ++reservations; } queue.put(msg); } private class LoggerThread extends Thread { public void run() { try { while (true) { try { synchronized (LogService.this) { if (isShutdown && reservations == 0) break; } String msg = queue.take(); synchronized (LogService.this) { --reservations; } writer.println(msg); } catch (InterruptedException e) { /* retry */ } } } finally { writer.close(); } } } } 

This is a snippet from the Java Concurrency book in practice, and I think that perhaps the reservations counter is not needed, since we could just use queue.size() to get the number of elements in the queue .

I'm right?

+8
java multithreading concurrency
source share
2 answers

No, that would actually create a dead end.

You will need to synchronize put and take if you want to use size in parallel. But take blocked, and now you will have a blocking take call synchronized on the same object as the put call. take cannot take values โ€‹โ€‹until something is put . put cannot be placed until take releases the lock. This is a dead end.

+5
source share

Using the variable โ€œreservationsโ€ is a good domain design because it is much more significant than the size, you can use this to express the concept of the domain, for example, the total number of reservations available, etc.

Performance side

ArrayBlockingQueue - the size call function will cause slowness, as it gets a lock to read the size, and this will slow down the operation or perform the operation.

LinkedBlockingQueue Caller size is atomic / volatile and has performance.

0
source share

All Articles