How to understand this CCAS locking machanizion used in AKKA? - java

I just came across a piece of code in akka.
https://codereview.scala-lang.org/fisheye/browse/~raw,r=25521/scala-svn/scala/trunk/test/files/presentation/akka/src/akka/util/LockUtil.scala
The core methods I am interested in is listed below.
/**
* A very simple lock that uses CCAS (Compare Compare-And-Swap)
* Does not keep track of the owner and isn't Reentrant, so don't nest and try to stick to the if*-methods
*/
class SimpleLock {
val acquired = new AtomicBoolean(false)
def ifPossible(perform: () => Unit): Boolean = {
if (tryLock()) {
try {
perform
} finally {
unlock()
}
true
} else false
}
def tryLock() = {
if (acquired.get) false
else acquired.compareAndSet(false, true)
}
def tryUnlock() = {
acquired.compareAndSet(true, false)
}
There are two related subquestions.
1) What's purpose of this class SimpleLock
2) Any hints or background knowledge about how it works?
I think since this code is written in both JAVA and scala, it leverages the AtomicBoolean class.
So I'd add java tag also.
Any advice is welcome! Not sure why someone vote this question close.
Related:
Can anyone interpret this C++ code (from OpenJDK6) into plain English?

Here is my understanding of the code. It used a acquired(AtomicBoolean) as a mutex. If any thread tries to acquire the lock , then it will set acquired to be true. then any other thread cannot acquired the lock due to they will get true from acquired and returned false until this acquired is set back to false by this thread.
Since acquired is not from a collection, it will not have ABA problem. So it can work.
Please correct me if I am wrong.

Related

System.out.println on my boolean made my program able to validate the boolean

My program is based on two threads that share a protocol object. Depending on a boolean in the shared protocol object I try to make the other thread wait before using the protocol.
Main:
GameProtocol protocol = new GameProtocol();
MyThreadedClass thread1 = new MyThreadedClass(protocol);
MyThreadedClass thread2 = new MyThreadedClass(protocol);
thread1.start()
thread2.start()
Thread class:
GameProtocol protocol;
private MyThreadedClass(GameProtocol protocol){
this.protocol = protocol
}
private GamePackage waitCheck(GamePackage gp){
if(!gp.isWaiting()) {
return protocol.update(gp);
}
while(protocol.waitForCategory) {
//System.out.println(protocol.waitForCategory);
}
return protocol.update(gp);
}
Protocol class:
boolean waitForCategory = false;
public synchronized GamePackage update(GamePackage gp){
if(gp.myTurnToPickCategory){
gp.setWaiting(false);
waitForCategory = true;
} else {
gp.setWaiting(true);
waitForCategory = false;
}
return gp;
}
Now my intention is to make one thread wait untill the other thread have used the update method a second time. But the second thread get stuck in the while loop even tho the boolean waitForCategory have been set to false. Once I added the line System.out.println(protocol.waitForCategory); however it just started to work, and if I remove it it stops working again. I can't seem to understand how a ´sout´ on the boolean make it work. If anyone understands this would it be possible to solve it in another way? as having a sout inside a loop like that will make it messy.
As others have already explained, the introduction of println() inserts synchronization into the picture, so your code gives the illusion that it works.
In order to solve this problem you have to make sure everything is properly synchronized. In other words, gp.isWaiting() must also be synchronized, and protocol.waitForCategory must be moved into a method and synchronized.
Alternatively, quit trying to work with synchronization and use asynchronous message passing via java.util.concurrent.BlockingQueue instead. Your code will perform better, you will not be running the danger of race conditions, and your code will also be testable. (Whereas with synchronization your code will never be testable, because there is no test that will catch a race condition.)

How to check if thread holds the monitor in IntelliJ?

While working on IntelliJ , I am unable to check that if the thread is holding the lock or not.
On eclipse GUI there is a lock like icon against the thread , telling us that it is holding that lock.
In below code snapshot, my thread is at notifyElementAdded() and holding the lock however, in a thread stack there is no such Icon or intimation from Intellij
So my question is how to check the same on IntelliJ GUI.
There is actually a boolean attribute to the Thread class in Java - Thread.holdsLock().
To get the name of the thread which holds the monitor you can use the code example below:
public static long getMonitorOwner(Object obj)
{
if (Thread.holdsLock(obj))
{
return Thread.currentThread().getId();
}
}
I don't think there is a similar functionality. But you can still check by getting the dump
You can click on Get Thread Dump in Debug window and then you can see the locked in the log to see that the thread is actually holding the lock
Create a custom variable in the Intellij debugging console using the plus button as shown in the image below.
Now every time you run the code in the debug mode, this variable will be re-calculated at your all debug points.
I created a variable- Thread.holdsLock(AwsS3ClientHelper.class) since I was acquiring a lock on the class itself. You can write any variable of your choice there. In your particular case, it will be Thread.holdsLock(observers).
This can be a potential feature request for IntelliJ to include this to their GUI product.
Programmatically, to verify this you can use the java.lang.Thread.holdsLock() method which returns true if and only if the current thread holds the monitor lock on the specified object
public static boolean holdsLock(Object obj)
Below snippet of run method for reference,
public void run() {
/* returns true if thread holds monitor lock */
// returns false
System.out.println("Holds Lock = " + Thread.holdsLock(this));
synchronized (this) {
// returns true
System.out.println("Holds Lock = " + Thread.holdsLock(this));
}
}

How compareAndSet works internally in redis

spring-data-redis module contains RedisAtomicLong class.
In this class you can see
public boolean compareAndSet(long expect, long update) {
return generalOps.execute(new SessionCallback<Boolean>() {
#Override
#SuppressWarnings("unchecked")
public Boolean execute(RedisOperations operations) {
for (;;) {
operations.watch(Collections.singleton(key));
if (expect == get()) {
generalOps.multi();
set(update);
if (operations.exec() != null) {
return true;
}
}
{
return false;
}
}
}
});
}
My question is why it works?
generalOps.multi() starts transaction after get() is invoked. It means that there is possibility that two different thread (or even client) can change value and both of them will succeed.
Is operations.watch prevent it somehow? JavaDoc doesn't explain purpose of this method.
PS: Minor question: why for (;;)? There is always one iteration.
Q: Is operations.watch prevent it somehow?
YES.
Quoting from Redis documentation about transaction:
WATCH is used to provide a check-and-set (CAS) behavior to Redis transactions.
WATCHed keys are monitored in order to detect changes against them. If at least one watched key is modified before the EXEC command, the whole transaction aborts, and EXEC returns a Null reply to notify that the transaction failed.
You can learn more about Redis transaction from that documentation.
Q: why for (;;)? There is always one iteration.
It seems the code you've posted is very old. From Google's cache of this url, I saw the code you provided which is dated back to Oct 15th, 2012!
Latest codes look much different:
compareAndSet method
CompareAndSet class
Is operations.watch prevent it somehow?
YES. After watching a key, if the key has been modified before transaction finishes, EXEC will fail. So if EXEC successes, the value is guaranteed to be unchanged by others.
why for (;;)? There is always one iteration.
In your case, it seems the infinite loop is redundant.
However, if you want to implement a check-and-set operation to modify the value with the old value, the infinite loop is necessary. Check this example from redis doc:
WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC
Since EXEC might fail, you need to retry the whole process in a loop until it successes.
RedisAtomicLong.compareAndSet implementation is not optimal since it requires 5 requests to Redis
Redisson - Redis Java client provides more efficient implementation.
org.redisson.RedissonAtomicLong#compareAndSetAsync method implemented using atomic EVAL-script:
"local currValue = redis.call('get', KEYS[1]); "
+ "if currValue == ARGV[1] "
+ "or (tonumber(ARGV[1]) == 0 and currValue == false) then "
+ "redis.call('set', KEYS[1], ARGV[2]); "
+ "return 1 "
+ "else "
+ "return 0 "
+ "end",
This script requires only single request to Redis.
Usage example:
RAtomicLong atomicLong = redisson.getAtomicLong("myAtomicLong");
atomicLong.compareAndSet(1L, 2L);

How to make an async listener do blocking?

I am writing a blackberry app that communicates with a simple Bluetooth peripheral using text based AT commands - similar to a modem... I can only get it working on the blackberry using an event listener. So the communication is now asynchronous.
However, since it is a simple device and I need to control concurrent access, I would prefer to just have a blocking call.
I have the following code which tries to convert the communications to blocking by using a wait/notify. But when I run it, notifyResults never runs until getStringValue completes. i.e. it will always timeout no matter what the delay.
The btCon object runs on a separate thread already.
I'm sure I am missing something obvious with threading. Could someone kindly point it out?
Thanks
I should also add the the notifyAll blows up with an IllegalMonitorStateException.
I previously tried it with a simple boolean flag and a wait loop. But the same problem existed. notifyResult never runs until after getStringValue completes.
public class BTCommand implements ResultListener{
String cmd;
private BluetoothClient btCon;
private String result;
public BTCommand (String cmd){
this.cmd=cmd;
btCon = BluetoothClient.getInstance();
btCon.addListener(this);
System.out.println("[BTCL] BTCommand init");
}
public String getStringValue(){
result = "TIMEOUT";
btCon.sendCommand(cmd);
System.out.println("[BTCL] BTCommand getStringValue sent and waiting");
synchronized (result){
try {
result.wait(5000);
} catch (InterruptedException e) {
System.out.println("[BTCL] BTCommand getStringValue interrupted");
}
}//sync
System.out.println("[BTCL] BTCommand getStringValue result="+result);
return result;
}
public void notifyResults(String cmd) {
if(cmd.equalsIgnoreCase(this.cmd)){
synchronized(result){
result = btCon.getHash(cmd);
System.out.println("[BTCL] BTCommand resultReady: "+cmd+"="+result);
result.notifyAll();
}//sync
}
}
}
Since both notifyResults and getStringValue have synchronized clauses on the same object, assuming getStringValues gets to the synchronized section first notifyResults will block at the start of the synchronized clause until getStringValues exits the synchronized area. If I understand, this is the behaviour you're seeing.
Nicholas' advice is probably good, but you may not find any of those implementations in BlackBerry APIs you're using. You may want to have a look at the produce-consumer pattern.
It may be more appropriate to use a Latch, Semaphore, or a Barrier, as recommended by Brian Goetz book Java Concurrency in Practice.
These classes will make it easier to write blocking methods, and will likely help to prevent bugs, especially if you are unfamiliar with wait() and notifyAll(). (I am not suggesting that YOU are unfamiliar, it is just a note for others...)
The code will work ok. If you will use final object instead of string variable. I'm surprised that you don't get NPE or IMSE.
Create field:
private final Object resultLock = new Object();
Change all synchronized sections to use it instead of string field result.
I don't like magic number 5 sec. I hope you treat null result as timeout in your application.

How do I perform a Unit Test using threads? [duplicate]

This question already has answers here:
How should I unit test multithreaded code?
(29 answers)
Closed 5 years ago.
Executive Summary: When assertion errors are thrown in the threads, the unit test doesn't die. This makes sense, since one thread shouldn't be allowed to crash another thread. The question is how do I either 1) make the whole test fail when the first of the helper threads crashes or 2) loop through and determine the state of each thread after they have all completed (see code below). One way of doing the latter is by having a per thread status variable, e.g., "boolean[] statuses" and have "statuses[i] == false" mean that the thread failed (this could be extended to capture more information). However, that is not what I want: I want it to fail just like any other unit test when the assertion errors are thrown. Is this even possible? Is it desirable?
I got bored and I decided to spawn a bunch of threads in my unit test and then have them call a service method, just for the heck of it. The code looks approximately like:
Thread[] threads = new Thread[MAX_THREADS];
for( int i = 0; i < threads.length; i++ ) {
threads[i] = new Thread( new Runnable() {
private final int ID = threadIdSequenceNumber++;
public void run() {
try {
resultRefs[ID] = runTest( Integer.toString( ID ) ); // returns an object
}
catch( Throwable t ) {
// this code is EVIL - it catches even
// Errors - don't copy it - more on this below
final String message = "error testing thread with id => "
+ ID;
logger.debug( message, t );
throw new IllegalStateException( message, t );
// need to wrap throwable in a
// run time exception so it will compile
}
}
} );
}
After this, we will loop through the array of threads and start each one. After that we will wait for them all to finish. Finally, we will perform some checks on the result references.
for( Thread thread : threads )
thread.start();
logger.debug( "waiting for threads to finish ..." );
boolean done = false;
while( !done ) {
done = true;
for( Thread thread : threads )
if( thread.isAlive() )
done = false;
}
for( int i = 0; i < resultRefs.length; i++ ) {
assertTrue( "you've got the world messed, dawg!",
myCondition(resultRefs[i]) );
Here's the problem. Did you notice that nasty try-catch-throwable block? I just added that as a temporary hack so I could see what was going on. In runTest( String ) a few assertions are made, e.g., assertNotNull( null ), but since it is in a different thread, it doesn't cause the unit test to fail!!!!
My guess is that we will need to somehow iterate over the threads array, check the status of each, and manually cause an assertion error if the thread terminated in a nasty way. What's the name of the method that gives this information (the stack trace of the dead thread).
Concurrency is one of those things that are very difficult to unit test. If you are just trying to test that the code inside each thread is doing what it is supposed to test, may be you should just test this code isolated of the context.
If in this example the threads collaborate to reach a result, may be you can test that collaboration without using threads. That would be done by executing all the collaborative parts sequentially.
If you want to test for race conditions and these kind of things, unit testing is not the best way. You will get tests that sometimes fail and sometimes don´t fail.
To summarize, I think that may be your problem is that you are unit testing in a level too high.
Hope this helps
The Google Testing Blog had an excellent article on this subject that's well worth reading: http://googletesting.blogspot.com/2008/08/tott-sleeping-synchronization.html
It's written in Python, but I think the principles are directly transferable to Java.
Unit testing in a multithreaded environment is tough... so some adjustments need to be made. Unit tests must be repeatable.. deterministic. As a result anything with multiple threads fails this criteria. Tests with multiple threads also tend to be slow.
I'd either try to see if I can get by with testing on a single thread.. does the logic under test really need multiple threads.
If that doesn't work, go with the member variable approach that you can check against an expected value at the end of the test, when all the threads have finished running.
Hey seems like there's another question just like this. Check my post for a link to a longer discussion at the tdd yahoogroup
Unit testing a multithreaded application?
Your runnable wrapper should be passing the exception object back to your test class and then you can store them in a collection. When all the tests are finish you can test the collection. If it isn't empty, iterate over each of the exceptions and .printStackTrace() then fail.
Implement a UncaughtExceptionHandler that sets some flags (which the Threads peridocially check) and set it on each Thread.
Another popular option for Junit concurrent thread testing is Matthieu Carbou's method using a custom JunitRunner and a simple annotation.
See the full documentation
It is possible making the unit test to fail, by using a special synchronization object. Take a look at the following article:
Sprinkler - Advanced synchronization object
I'll try to explain the main points here.
You want to be able to externalize internal threads failures to the main thread, which, in your case is the test. So you have to use a shared object/lock that both the internal thread and the test will use to sync each other.
See the following test - it creates a thread which simulates a thrown exception by calling a shared object named Sprinkler.
The main thread (the test) is blocked on Sprinkler.getInstance().await(CONTEXT, 10000)
which, by the time release is called - will be free and catch the thrown exception.
In the catch block you can write the assert which fails the test.
#Test
public void testAwait_InnerThreadExternalizeException() {
final int CONTEXT = 1;
final String EXCEPTION_MESSAGE = "test inner thread exception message";
// release will occur sometime in the future - simulate exception in the releaser thread
ExecutorServiceFactory.getCachedThreadPoolExecutor().submit(new Callable<void>() {
#Override
public Void call() throws Exception {
Sprinkler.getInstance().release(CONTEXT, new RuntimeException(EXCEPTION_MESSAGE));
return null;
}
});
Throwable thrown = null;
try {
Sprinkler.getInstance().await(CONTEXT, 10000);
} catch (Throwable t) {
// if the releaser thread delivers exception it will be externelized to this thread
thrown = t;
}
Assert.assertTrue(thrown instanceof SprinklerException);
Assert.assertEquals(EXCEPTION_MESSAGE, thrown.getCause().getMessage());
}

Categories

Resources