I'm struggling with some concurrent legacy code and wonder whether stopLatch and/or mode should be volatile:
public class MyClass {
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private MyModeEnum mode = MyModeEnum.NONE;
private CountDownLatch stopLatch;
public synchronized void start(final MyModeEnum mode) {
assert mode != null && mode != MyModeEnum.NONE;
if (isRunning()) {
// Throw an exception.
}
this.mode = mode;
stopLatch = new CountDownLatch(1);
executor.execute(() -> {
try {
// Pre and post operations not under control around stopLatch.await().
} catch (final Exception e) {
stop();
// Further exception handling.
} finally {
MyClass.this.mode = MyModeEnum.NONE;
}
});
}
public synchronized void stop() {
if (!isRunning()) {
return;
}
stopLatch.countDown();
}
public boolean isRunning() {
return mode != MyModeEnum.NONE;
}
public MyModeEnum getMode() {
return mode;
}
}
Elaborate explanation very appreciated.
EDIT: I wasn't able to boil down general questions/answers such as When exactly do you use the volatile keyword in Java? to this particular problem.
According to the most upvoted comments:
Mick Mnemonic:
isRunning() is not synchronized, so mode should be volatile.
Brian Goetz:
You have data races on mode. It is accessed from outside the sync block. First choice should be to synchronize isRunning and getMode; making mode volatile is a more advanced play. (Walk first, then fly.)
Related
class PublishService {
public void longRunningPublish() {
...
}
}
From different places in code, the method can be invoked.
caller1.longRunningPublish();
caller2.longRunningPublish();
...
callerN.longRunningPublish();
Question: how can I prevent longRunningPublish running concurrently? Each invocation should stack and be delay, and only start when the previous run has finished.
Could I do better than the following?
class PublishService {
private boolean running;
public void throttleLongRunningPublish() {
while (running) {
TimeUnit.SECONDS.sleep(10);
}
running = true;
try {
longRunningPublish();
} finally {
running = false;
}
}
}
Your code is not thread safe.
If you create multiple instances of PublishService and run them concurrently the boolean variable has no effect.
If your instance of PublishService is a singleton and the same class is executed by different threads there there is no guarantee that the method will be executed serially because multiple thread could enter the method before reaching the instruction:
running = true;
This is a simple example than handles serialization if there are multiple instances of the same class along with a "demo" main
public class PublishService {
private static final Logger logger= LoggerFactory.getLogger(PublishService.class.getName());
private static final Lock lock=new ReentrantLock();
public void longRunningPublish() {
lock.lock();
try {
logger.info("{} longRunningPublish before sleep",Thread.currentThread().getId());
Thread.sleep(500);
logger.info("{} longRunningPublish after sleep",Thread.currentThread().getId());
} catch (InterruptedException e) {
logger.error(e.getMessage(),e);
} finally {
lock.unlock();
}
}
public static void main(String args[]) {
ExecutorService executor=Executors.newFixedThreadPool(10);
for(int i=0;i<20;i++) {
executor.submit(() -> {
PublishService publishService = new PublishService();
publishService.longRunningPublish();
});
}
}
}
If the class is a singleton you can remove the static qualifier of the lock variable.
In order to prevent concurrent access, you need to lock the resource while it is being used with something like a ReentrantLock. If you need to guarantee in-order access, you can use the constructor ReentrantLock(boolean fair) with fair set to true. Otherwise, you can use a basic ReentractLock or the synchronized property.
I found a neat way with Semaphore:
class PublishService {
private static final Semaphore lock = new Semaphore(1);
public void throttleLongRunningPublish() {
try {
lock.tryAcquire(2, TimeUnit.MINUTES);
longRunningPublish();
} finally {
lock.release();
}
}
}
I want to let a thread sleep until a certain condition becomes off. Basically, I need three operations:
enable(): enable sleeping mode (do nothing if already enabled)
disable(): disable sleeping mode (do nothing if already disabled)
await(): wait until sleeping mode becomes disabled (or return immediately if the sleeping mode was already disabled) or the thread becomes interrupted (InterruptedException is thrown)
With this, thread A calls enable(). Now thread B calls await() and goes to sleep until thread A (or another one) calls disable(). This cycle can be repeated.
I know this can be quite easily done with wait() and notify(), but I am wondering if JDK8 has such functionality built-in?
The closest I could find is was a CountdownLatch(1), unfortunately the implementation is not resettable.
Basically, I just want to call enable()/disable() and await(), while all concurrency concepts are abstracted in the implementation (though await() should throw InterruptedException, which is unavoidable).
You could use Condition :
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Switch {
private final Lock lock = new ReentrantLock();
private final Condition on = lock.newCondition();
private final Condition off = lock.newCondition();
private volatile boolean state = true;
public void enable() {
try {
lock.lock();
state = true;
on.signalAll();
} finally {
lock.unlock();
}
}
public void disable() {
try {
lock.lock();
state = false;
off.signalAll();
} finally {
lock.unlock();
}
}
public void await() {
try {
lock.lock();
while(!state) {
try {
off.await();
} catch (InterruptedException e) {
throw new RuntimeException("waiting interrupted.");
}
}
} finally {
lock.unlock();
}
}
}
Another possible implementation of Switch:
public class Switch {
private final AtomicBoolean state = new AtomicBoolean();
public void enable() {
state.set(true);
}
public void disable() {
if (state.compareAndSet(true, false)) {
synchronized (state) {
state.notifyAll();
}
}
}
public void await() throws InterruptedException {
if (state.get()) {
synchronized (state) {
while (state.get()) {
state.wait();
}
}
}
}
}
enable(): enable sleeping mode (do nothing if already enabled)
disable(): disable sleeping mode (do nothing if already disabled)
do nothing if already enabled (disabled) is a bad design, which can lead to subtle bugs which are hard to reproduce and discover. For example, let sleeping mode is disabled, and one thread calls disable() and the other calls enable(). Depending on which call is made first, the mode will stay enabled or disabled forever. To make execution more deterministic, enabling and disabling must be counted, and the final state will be determined (disabled).
Instead, your threads should exchange tokens which do not mask each other. Besides CountdownLatch, (which effectively is a counter of prohibitions), JDK has CyclicBarrier and Phaser, which are resettable counters of prohibitions, and Semaphore, which is a counter of permissions.
UPDT
this implementation may work (I did not tested it):
Phaser p = new Phaser(1);
public void await() {
p.arriveAndAwaitAdvance();
}
public void enable() {
p.register();
}
public void disable() {
p.arriveAndDeregister();
}
N sequential calls to enable() require the same number of disable() to pass the awaiting thread.
You could use a Semaphor too :
import java.util.concurrent.Semaphore;
public class Switch {
private Semaphore semaphore = new Semaphore(1);
public void enable() {
synchronized(this) {
semaphore.drainPermits(); // 0
semaphore.reducePermits(1); // -1 or 0
}
}
public void disable() {
semaphore.release(2); // 1 or 2
}
public void await() throws InterruptedException {
semaphore.acquire();
semaphore.release();
}
}
This question already has answers here:
How do determine if an object is locked (synchronized) so not to block in Java?
(8 answers)
Closed 6 years ago.
I have synchronisation block in syncCmd function:
public Object Sync = new Object();
public void syncCmd(String controlCmd) {
synchronized(Sync) {
...
}
}
I need to add some logic in case if one thread has occupied Sync and doing its job. In this case I would like to report "too busy" to system and not get to queue. What is the best way to know if somebody has occupied Sync section? How to know how many threads is waiting in this section? Everything is in Java 1.4.
Have a look at the Lock interface and its implementation ReentrantLock. It allows you to use tryLock() method, including the variant that allows to wait for some time if the resource is already locked:
private ReentrantLock lock = new ReentrantLock();
public void syncCmd(String controlCmd) {
if (lock.tryLock()) {
try {
// Use your synchronized resource here
} finally {
lock.unlock();
}
} else {
// Failed to lock
}
}
Java 1.4, unfortunately, has no java.util.concurrency package and I think the best choice you have is to implement the same logic by means of synchronized and double checks:
public class Lock {
private final Object lock = new Object();
private volatile boolean locked = false;
public boolean tryLock() {
if (!locked) {
synchronized (lock) {
if (!locked) {
locked = true;
return true;
}
}
}
return false;
}
public void unlock() {
synchronized (lock) {
locked = false;
}
}
}
It will not work as fast as ReentrantLock that uses CAS loop backed by processor instructions in modern JVMs, but it will do the job.
This implementation is also not reentrant, you can extend it to track the locking thread and locks count if you need reentrance.
Important update: #Stephen C made a good point that double check is broken in Java 1.4 and one always must keep it in mind. But there're exceptions. For instance, short primitive types. So, I think it will work in this particular case. For more details, please, look at the "Double-Checked Locking is Broken" Declaration.
Synchronized blocks / methods and primitive mutexes can't do that in Java.
But if you use a Lock instead (javadoc), you can use tryLock either to never block or to only block for a limited time.
Example:
Lock l = new ReentrantLock();
if (l.tryLock()) {
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
else {
// report "too busy"
}
But note that it is essential to use "try ... finally" and an explicit unlock() call to ensure that the lock is always released. (Unlike the synchronized constructs, which takes care of that for you automatically.)
Prior to Java 1.5 there is no solution that I am aware of in pure Java. It might be possible with native code trickery, but I don't know how.
You / your management should be looking to ditch support in your products for Java 1.4, and to migrating away from any third-party product that depends on top of it. Java 1.5 itself was EOL'd many years ago. In fact, all releases prior to Java 1.8 have been EOL'd; see the Oracle Java SE Support Roadmap document.
Two of the answers above talked about java.util.concurrent.locks.ReentrantLock, but it doesn't exist in Java 1.4.
Too bad so sad?
No! If system libraries and 3rd party libraries don't hand you what you want, then write it yourself!
The code below does what you asked for, and absolutely nothing more. I personally would not use it without first adding some features that would make it more useable, more testable, and most importantly, more foolproof.
I'm just offering it to you as an example of where to begin.
public class ExtremelySimplisticNonReentrantLock {
boolean isLocked = false;
/**
* #return true if the lock was acquired, false otherwise.
*/
public synchronized boolean tryToAcquire() {
if (isLocked) {
return false;
}
isLocked = true;
return true;
}
public synchronized void release() {
lsLocked = false;
}
}
Share and Enjoy!
Try this (Two classes - Executor and Tracker ) :
Executor :
package com.example.so.jdk1_4.synch;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
/**
* <p> For http://stackoverflow.com/questions/38671520/not-wait-in-case-synchronized-section-is-occupied </p>
* #author Ravindra HV
*/
public class InUseExample {
public synchronized void execute(String command) {
InUseTracker.obtainClassInstance().setInuse(true);
try {
System.out.println("Executing :"+command);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}// do work
InUseTracker.obtainClassInstance().setInuse(false);
}
/**
* #param args
*/
public static void main(String[] args) {
System.out.println("Start :"+new Date());
testInUseExample();
System.out.println("Final wait count :"+InUseTracker.obtainClassInstance().waitCount());
System.out.println("End :"+new Date());
}
private static void testInUseExample() {
final InUseExample inUseExample = new InUseExample();
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
InUseTracker.obtainClassInstance().incrementWaitCount();
while(true) {
if( InUseTracker.obtainClassInstance().isInuse() == false ) { // reduces the chances of this thread going to a block mode..
inUseExample.execute(Thread.currentThread().getName());
break;
}
else {
try {
Random random = new Random();
String message = Thread.currentThread().getName()+" - block in use by :"+InUseTracker.obtainClassInstance().getInUseBy();
message = message+" "+". Wait Count :"+InUseTracker.obtainClassInstance().waitCount();
System.out.println(message);
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
InUseTracker.obtainClassInstance().decrementWaitCount();
}
}
};
int threadCount = 10;
List<Thread> threadPoolTemp = new ArrayList<Thread>();
for(int i=0;i<threadCount;i++) {
Thread thread = new Thread(runnable);
threadPoolTemp.add(thread);
}
for (Thread thread : threadPoolTemp) {
thread.start();
}
for (Thread thread : threadPoolTemp) {
try {
thread.join(); // wait until all threads have executed..
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Tracker :
package com.example.so.jdk1_4.synch;
/**
* <p> For http://stackoverflow.com/questions/38671520/not-wait-in-case-synchronized-section-is-occupied </p>
* #author Ravindra HV
*/
public class InUseTracker {
private boolean inuse;
private int waitCount;
private String inUseBy;
private static InUseTracker DEFAULT_INSTANCE = new InUseTracker();
private InUseTracker() {
}
public static InUseTracker obtainClassInstance() {
return DEFAULT_INSTANCE;
}
public synchronized boolean isInuse() {
return inuse;
}
public synchronized void setInuse(boolean inuse) {
this.inuse = inuse;
if(inuse) {
setInUseBy(Thread.currentThread().getName());
}
else {
setInUseBy("");
}
}
private void setInUseBy(String inUseBy) {
this.inUseBy = inUseBy;
}
public synchronized String getInUseBy() {
return inUseBy;
}
public synchronized void incrementWaitCount() {
waitCount++;
}
public synchronized void decrementWaitCount() {
waitCount--;
}
public synchronized int waitCount() {
return waitCount;
}
}
PS: Guess you'd have to move the
InUseTracker.obtainClassInstance().setInuse(false);
within a finally if or as appropriate.
I had implemented a asynchronous thread by a singleton class in which a queue is present to which i add logging object.
But it is giving no such element exception at java.util.linkedlist.remove
public class LogDaoSingleton extends Thread {
private static LogDaoSingleton logDaoSingleton = new LogDaoSingleton();
private static Queue<ScoreLoggingObject> queue = new LinkedList<ScoreLoggingObject>();
private static Boolean firstTime = true;
private LogDAO logDAO;
private SkipLogDaoImpl skipLogDAO;
Connection conNull = null;
Connection connection = null;
private int counter = 0;
Connection con = null;
Connection skipCon = null;
public static LogDaoSingleton getInstance() {
return logDaoSingleton;
}
private static void createInstance() {
logDaoSingleton = new LogDaoSingleton();
}
private LogDaoSingleton() {
try {
con = HMDBUtil.getNonTxNullProdConnection();
conNull = HMDBUtil.getNonTxNullProdConnection();
skipCon = HMDBUtil.getNonTxNullProdConnection();
logDAO = new LogDAOImpl();
skipLogDAO = new SkipLogDaoImpl();
hmCandScoreLog = PropertyReader.getStringProperty(
CacheConstants.CLUSTER_REPORT,
CacheConstants.HM_CAND_SCORE_LOG);
hmCandScoreLogNull = PropertyReader.getStringProperty(
CacheConstants.CLUSTER_REPORT,
CacheConstants.HM_CAND_SCORE_LOG_NULL);
} catch (HMCISException e) {
e.printStackTrace();
}
}
public static void addtoQueue(ScoreLoggingObject scoringObject) {
queue.add(scoringObject);
if (firstTime) {
synchronized (firstTime) {
if (firstTime) {
createInstance();
logDaoSingleton.setDaemon(false);
logDaoSingleton.start();
firstTime = false;
}
}
}
}
public void run() {
try {
while (true) {
try {
if (null != queue && queue.size() > 0) {
logData(queue.poll());
} else {
try {
Thread.sleep(2 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
// Do nothing.
}
}
} catch (Throwable e) {
firstTime = true;
}
}
private void logData(ScoreLoggingObject scoreLoggingObject) {
}
}
}
Error is at logData(queue.poll());
There are at least three problems in this method:
public static void addtoQueue(ScoreLoggingObject scoringObject) {
queue.add(scoringObject);
if (firstTime) {
synchronized (firstTime) {
if (firstTime) {
createInstance();
logDaoSingleton.setDaemon(false);
logDaoSingleton.start();
firstTime = false;
}
}
}
}
Namely
That you are adding to a LinkedList without a lock. LinkedList is not a concurrency safe collection. Try ConcurrentSkipLinkedList as a better collection.
You are reading firstTime using double-checked locking... which can have side-effects that you might not believe... Go take a look at "Java Concurrency in Practice" specifically the Yuck-face listing on page 32. Try to predict what that program will output before reading the book. Then read the explanation. Unfortunately I am going to have to spoil the impact of that example for you now when I point out that the JVM is entitled to reorder operations in between synchronization points. So the result is that the operations within your synchronized block can be implemented in any order... for example they could happen in the following order (likely not, but a JVM implementation will still be valid if it did it in this order)
synchronized (firstTime) {
if (firstTime) {
firstTime = false;
createInstance();
logDaoSingleton.setDaemon(false);
logDaoSingleton.start();
}
}
What would happen if there is an exception thrown in your createInstance() method?
If it were me, I would fix that by making firstTime a volatile that would force the JVM to respect the ordering (though you would still need the double-check!)
firstTime is a Boolean initialized by auto-boxing, which for Boolean uses pooled instances, so your double-checked lock is actually synchronized (Boolean.TRUE) and not synchronized (firstTime). Additionally it is bad form to synchronize on a non-final field, as it almost never does what you want it to do. You probably want to just make the addToQueue method synchronized until you know you have a problem.
TL;DR you are trying to be 'clever' with locking... always a bad plan... especially before you know that you need to be clever. Write the simplest thing that could possibly work, then get on with the rest of the problems. Then see where the performance issues are... ONLY THEN should you worry about locking in this class.
I have a class named "Channel" with two methods defined:
class Channel {
void read(){...}
void write(){...}
}
There's an instance of this class used in multi-threaded environment. Several threads periodically read from channel while one thread periodically writes to it. Read operation is thread-safe so that it is ok for several reads to occur simultaneously. However once write operation starts, read threads must be blocked until write operation is finished. It is essential to keep read operations as fast as possible and avoid resource-consuming synchronization routines.
What would be the most appropriate pattern to implement such behaviour? Maybe java classes or libraries to help?
Use a ReadWriteLock. It will allow concurrent reads to occur with serial writes. To further satisfy your requirements, an acquisition of a writeLock will prevent any readLock's from making progress until a subsequent release.
class Channel {
final ReadWriteLock lock = new ReentrantReadWriteLock();
void read(){
lock.readLock().lock();
try{
}finally{
lock.readLock().unlock();
}
}
void write(){
lock.writeLock().lock();
try{
}finally{
lock.writeLock().unlock();
}
}
}
For fun, here's an implementation using the new Java 7 try-with-resources feature.
class RWLock {
class ACLock extends ReentrantLock implements AutoCloseable {
public void close() {
this.unlock();
}
}
private ACLock readLock = ACLock();
private ACLock writeLock = ACLock();
private int numReaders = 0
public AutoCloseable write() {
readLock.lock();
writeLock.lock();
return new AutoCloseable() {
public void close() {
writeLock.close();
readLock.close();
}
}
}
public AutoCloseable read() {
try (ACLock read = readLock.acquire()) {
if (numReaders == 0) {
writeLock.lock();
}
numReaders++;
}
return new AutoCloseable() {
public void close() {
numReaders--;
if (numReaders == 0) {
writeLock.unlock();
}
}
}
}
// Here's how you use them
public static void main(String[] args) {
RWLock lock = RWLock();
try (AutoCloseable lock = RWLock.read()) {
// Do some readin'
}
try (AutoCloseable lock = RWLock.write()) {
// Do some writin'
}
}
}