application hanging

5 views
Skip to first unread message

gianluca

unread,
Nov 15, 2009, 7:05:56 AM11/15/09
to multiverse
Hi,

the following code prints "2000" at the end of execution if all
accesses to the object are handled correctly (and less than 2000 if
not):

-------------------------------------------
package unsafe;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.multiverse.api.annotations.*;

@AtomicObject
public class Unsafe {

int value=0;
Random r=new Random(System.currentTimeMillis());

public void setValue(int i){value=i;}
public int getValue(){return value;}

public void inc(){
int tmp=getValue();
setValue(tmp+1);
}

class Changer extends Thread{
public void run(){
for (int i = 0; i < 1000; i++) {
//System.out.println("inc");
inc();
}
}
}

public Unsafe(){
System.out.println("start");
Changer c1=new Changer();
Changer c2=new Changer();
c1.start();
c2.start();
try {
c1.join();
} catch (InterruptedException ex) {ex.printStackTrace();}
try {
c2.join();
} catch (InterruptedException ex) {ex.printStackTrace();}

System.out.println(getValue());

}

public static void main(String[] args) {
new Unsafe();
}

}
-------------------------------------------
it's a slightly modified version of the code I posted in thread
http://groups.google.com/group/googlemultiverse/browse_thread/thread/6f75da7c333aae8b.

Anyway, if I compile and run the code under Multiverse it seems to
hang after some iteration. I also see both my 2 cores nearly at 100%.

Gianluca

Christian Vest Hansen

unread,
Nov 15, 2009, 11:23:34 AM11/15/09
to googlemu...@googlegroups.com
Sorry about the off-topicness, but you shouldn't start threads in a constructor.

You could try to `kill -QUIT` the JVM to get a thread-dump (or inspect
it in VisualVM) and see what's keeping the cores busy.
> --
>
> You received this message because you are subscribed to the Google Groups "multiverse" group.
> To post to this group, send email to googlemu...@googlegroups.com.
> To unsubscribe from this group, send email to googlemultiver...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/googlemultiverse?hl=.
>
>
>



--
Venlig hilsen / Kind regards,
Christian Vest Hansen.

gianluca

unread,
Nov 15, 2009, 2:33:20 PM11/15/09
to multiverse
Thanks Christian,

I understand now that starting everything from a constructor which is
handled as a transaction doesn't help either... switching to
@AtomicMethod.

I noticed later what I guess is another problem in my code: the
"value" field should be volatile, right?

Gianluca

peter veentjer

unread,
Nov 16, 2009, 3:30:06 AM11/16/09
to multiverse
Hi Gianluca,

the cause of this 'hanging' is that transaction used in the changer
method sees a non committed version of the Unsafe and it keeps
retrying the transaction indefinitely (the default value for
retrycount is integer.max).

What you should do is create and commit the unsafe object before you
are going to pass it to other threads.

Transaction can be started best with the StmUtils.deferredExecute that
automatically executes tasks after the transaction commits. If you do
this within a transaction, it could be that you are starting many more
threads than expected because a transaction can be retried.

I'm going to do a checkin today containing a solution for this problem
that already is integrated in Multiverse (so no worries for you). A
transaction restart backoff policy is added with a exponential backoff
as default implementation that let threads sleep when they run into a
'recoverable' error. Because of this sleeping, the number of retries
is now lowered to 1000 en works fine with the integration tests.
> it's a slightly modified version of the code I posted in threadhttp://groups.google.com/group/googlemultiverse/browse_thread/thread/....

peter veentjer

unread,
Nov 16, 2009, 3:35:39 AM11/16/09
to multiverse
> I noticed later what I guess is another problem in my code: the
> "value" field should be volatile, right?

If you don't use an STM you need to make sure that you apply enough
synchronization, so a volatile could be sufficient for that.

With an STM, the field is managed by an STM and the STM has to make
sure that it applies enough synchronization. So no volatile or
synchronized needed on managed fields, this has all become task of the
STM.

Multiverse also guarantees a happens before relation between a start
and commit, so all changes made by a commit will be visible in each
following start. So also nothing to worry about.

PS:
I think something like this should work:

@AtomicObject
public class Unsafe {

int value=0;
final Random r=new Random(System.currentTimeMillis());

public void setValue(int i){value=i;}
public int getValue(){return value;}

public void inc(){
int tmp=getValue();
setValue(tmp+1);
}

static class Changer extends Thread{
final Unsafe unsafe;
Changer(Unsafe unsafe){
this.unsafe = unsafe;
}
public void run(){
for (int i = 0; i < 1000; i++) {
//System.out.println("inc");
inc();
}
}
}

public static void main(String[] args) {
Unsafe unsafe = new Unsafe();

System.out.println("start");
Changer c1=new Changer(unsafe);
Changer c2=new Changer(unsafe);
c1.start();
c2.start();
try {
c1.join();
} catch (InterruptedException ex) {ex.printStackTrace();}
try {
c2.join();
} catch (InterruptedException ex) {ex.printStackTrace();}

System.out.println(unsafe.getValue());
}

}
Reply all
Reply to author
Forward
0 new messages