How to simulate constructor race conditions? - java

I am reading "Java Concurrency in practice" and looking at the example code on page 51.
This states that if a thread has references to a shared object then other threads may be able to access that object before the constructor has finished executing.
I have tried to put this into practice and so I wrote this code thinking that if I ran it enough times a RuntimeException("World is f*cked") would occur. But it isn't doing.
Is this a case of the Java spec not guaranting something but my particular implementation of java guaranteeing it for me? (java version: 1.5.0 on Ubuntu) Or have I misread something in the book?
Code: (I expect an exception but it is never thrown)
public class Threads {
private Widgit w;
public static void main(String[] s) throws Exception {
while(true){
Threads t = new Threads();
t.runThreads();
}
}
private void runThreads() throws Exception{
new Checker().start();
w = new Widgit((int)(Math.random() * 100) + 1);
}
private class Checker extends Thread{
private static final int LOOP_TIMES = 1000;
public void run() {
int count = 0;
for(int i = 0; i < LOOP_TIMES; i++){
try {
w.checkMe();
count++;
} catch(NullPointerException npe){
//ignore
}
}
System.out.println("checked: "+count+" times out of "+LOOP_TIMES);
}
}
private static class Widgit{
private int n;
private int n2;
Widgit(int n) throws InterruptedException{
this.n = n;
Thread.sleep(2);
this.n2 = n;
}
void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}
}
}

You don't publish the reference until after the constructor has finished, change Widgit like this:
private class Widgit{ // NOTE: Not class is not static anymore
private int n;
private int n2;
Widgit(int n) throws InterruptedException{
this.n = n;
w = this; // publish reference
Thread.sleep(2);
this.n2 = n;
}
void checkMe(){
if (n != n2) {
throw new RuntimeException("World is f*cked");
}
}
Should now throw.
Edit: You should also declare the Widgit field as volatile:
private volatile Widgit w;

Well, you need to understand the issues a little more. It isn't really a case of anything being or not being "guaranteed." With concurrency problems, nothing is really guaranteed unless you really do specific things to force the problem to happen. You're just relying on the hope that enough runs should produce, which is not the case. These kinds of problems are hard to predict, which is why concurrency is a hard problem. You could try doing more work in your functions, but I assure you these are real problems that the runtime is not going to save you from.

Before sleeping, start a new thread which prints the value of n2. You will see the second thread can access the object before the constructor has finished.
The following example demonstrates this on the Sun JVM.
/* The following prints
Incomplete initialisation of A{n=1, n2=0}
After initialisation A{n=1, n2=2}
*/
public class A {
final int n;
final int n2;
public A() throws InterruptedException {
n = 1;
new Thread(new Runnable() {
public void run() {
System.out.println("Incomplete initialisation of " + A.this);
}
}).start();
Thread.sleep(200);
this.n2 = 2;
}
#Override
public String toString() {
return "A{" + "n=" + n + ", n2=" + n2 + '}';
}
public static void main(String... args) throws InterruptedException {
System.out.println("After initialisation " + new A());
}
}

This will never throw a RunTimeException because your Widgit instance variable w remains null until the constructor code has executed. While your main thread is sleeping in the Widgit constructor, your Checker instance is hitting NullPointerException constantly as the w variable is still null. When your main thread finishes construction, the two int variables in Widgit are equal.

Related

My custom semaphore doesn't seem to work in my program

Basically I have a method that I want to synchronize (only let one thread in at a time), however I'm not allowed to use the synchronized keyword for this particular practice. Instead, I decided to create a semaphore and just set the value to 1, therefore acting like a mutually exclusive lock (which is what I believe the synchronized keyword does right?).
So basically, my Semaphore class looks like this:
import java.util.*;
public class Semaphore
{
private int count = 0;
public Semaphore (int init_val) {
count = init_val;
}
public synchronized void P() {
count = count - 1;
while(count < 0) {
try {
wait();
} catch(InterruptedException e) {
}
}
}
public synchronized void V() {
count = count + 1;
notifyAll();
}
}
And I'm using it inside the method I want to synchronize like this (just an example):
Semaphore s = new semaphore(1);
int x = 0;
public void add() {
s.P()
int x = x + 1;
System.out.println(x);
s.V()
}
I have 100 threads calling the add method, but for some reason the value of x is concurrent, but not going up in order (race condition). I'm not sure what I'm doing wrong, any advice?

Dining Philosopher's solution ending up in deadlock

I've implemented the resource hierarchy solution to the Dining Philosopher's Problem. When I try to compare the two Chopsticks' n values, they end up in deadlock. However, if I use their hashCodes instead of n values, it runs smoothly. Why this difference? Aren't they both numbers at the end of the day?
import java.util.Random;
class Chopstick {
public final int n;
public Chopstick(int n) {
this.n = n;
}
}
class Philosopher extends Thread {
private Chopstick left, right;
private Random random;
private final int n;
public Philosopher(int n, Chopstick left, Chopstick right) {
this.n = n;
if (left.n > right.n) { // no deadlock if I replace this with left.hashCode() > right.hashCode()
this.right = left;
this.left = right;
} else {
this.left = left;
this.right = right;
}
this.random = new Random();
}
#Override
public void run() {
try {
while (true) {
Thread.sleep(random.nextInt(10)); // Think
synchronized(left) {
synchronized(right) {
System.out.println("P " + n + " eating");
Thread.sleep(random.nextInt(10));
}
}
}
} catch(InterruptedException ie) {
ie.printStackTrace();
}
}
}
class Main {
public static void main(String[] args) {
final int n = 3;
Chopstick[] sticks = new Chopstick[n];
Philosopher[] ps = new Philosopher[n];
for (int i = 0; i < n; i++) {
sticks[i] = new Chopstick(n);
}
for (int i = 0; i < n; i++) {
ps[i] = new Philosopher(i, sticks[i], sticks[(i + 1) % n]);
ps[i].start();
}
}
}
Your problem is related to the fact that you don't manage cases where left.n == right.n and unfortunately instead of initializing your Chopstick array with sticks[i] = new Chopstick(i), you used sticks[i] = new Chopstick(n) such that you have only cases of type left.n == right.n which are not properly managed so you get deadlocks.
As you did not override the method hashCode(), using hashCode() helps to avoid the problem because they are different instances of Chopstick with different values of hashCode() but you could still meet cases where we have 2 different instances of Chopstick with the same hashCode(). So you still have to manage cases where we have equal values.
The way to manage equal values properly is by using a third lock called the "tie breaking" lock
class Philosopher extends Thread {
// The tie breaking lock
private static Object tieLock = new Object();
...
private void printAndSleep() throws InterruptedException {
synchronized(left) {
synchronized(right) {
System.out.println("P " + n + " eating");
Thread.sleep(random.nextInt(10));
}
}
}
public void run() {
...
if (left.n == right.n) {
// Equal values so we need first to acquire the tie breaking lock
synchronized (tieLock) {
printAndSleep();
}
} else {
printAndSleep();
}
...
}
}
A more generic way to manage lock ordering is by relying on System.identityHashCode(obj) as value of each instance to sort instead of using a field's value or hashCode() because this way you won't depend on something specific to the target object's type.
More details in chapter 10.1.2 Dynamic lock order deadlock of Java Concurrency in Practice from Brian Goetz
The BUG is that you have
sticks[i] = new Chopstick(n);
when it should be
sticks[i] = new Chopstick(i);
The hash values of the objects will still be unique even if their data is the same since you haven't overridden the hashCode function.

How to block attributes from being used in java

Basically I would like to know if there is a way to "disable" an attribute within a block after a certain point.
For example check the following scenario:
for(int i=0;i<10;i++){
for(int j=i+5;j<50;j++){
//from here until end of the block I want to make sure I don't use **i** anymore.
print(j*5+i); //I want this line to produce compiler error
}
}
Don't get me wrong I understand it is a bad programming, but I still can't help but to use i,j,k,h as attributes. and sometimes I make a mistake by misplacing the attributes in wrong places.
Call a method.
for (int i = 0; i < 10; i++) {
for (int j = i + 5; j < 50; j++) {
doSomething();
}
}
...
private void doSomething() {
// Woot, no i and no j!
}
Your code doesn't make sense to anybody. You need to divide it into functions with good names so that anyone can understand what your program is doing without comments around the code or getting mixed up with variables.
Here's an example for the code you have posted:
public void printNumberTimes5(int number) {
print(number*5);
}
But don't stop there, make it obvious what the loop is doing too:
public void printSomeNumbers(int someNumber) {
for(int j=someNumber+5;j<50;j++){
printNumberTimes5(j);
}
}
And again:
public void printSomeNumbers_repeat(int repeat) {
for(int i=0;i<repeat;i++){
printSomeNumbers(i);
}
}
I don't really know what you're doing but renaming the function to what you're supposed to be doing would make it clear.
Remember: each function should only have one job.
Finally, give i and j real names so that you understand what those numbers do and don't mix them up.
The best way to obtain this in java, is by using scope. Make sure that the variables are in different scopes and then you don't have access to it. A good guideline to follow is to split your logic in various small methods, this way you'll ensure the desired behavior.
My recommendations in order of preference:
Use meaningful variable-names. Maybe i isn't as good as e.g. row, ...
Use functions to group operations and also reduce the variables they can access. This can also lead to a point where repeating operations can easily be reused.
Use a custom counter-object like this one
/**
* Created for http://stackoverflow.com/q/25423743/1266906
*/
public class ObliviousLoops {
public static void main(String[] args) {
for(LockableCounter i = new LockableCounter(0); i.getValue() < 42; i.unlock().increment()) {
System.out.println("A-loop:" + i.getValue());
i.lock();
// No access, everything is fine
}
for(LockableCounter i = new LockableCounter(0); i.getValue() < 42; i.unlock().increment()) {
System.out.println("B-loop1:" + i.getValue());
i.lock();
// Next statement will throw an Exception
System.out.println("B-loop2:" + i.getValue());
}
}
static class LockableCounter {
private long value;
private boolean locked;
LockableCounter(long value) {
this.value = value;
}
public LockableCounter lock() {
this.locked = true;
return this;
}
public LockableCounter unlock() {
this.locked = false;
return this;
}
public long getValue() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
return value;
}
public void increment() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
value++;
}
#Override
public String toString() {
if(locked) {
throw new IllegalStateException("Accessing locked counter");
}
return String.valueOf(value);
}
}
}
the most obvious draw-backs of the last solution is a less fluent handling of the value, less ways to optimize the operations for the compiler, ... in practice you may even want to replace the LockableCounter by something different, once you are sure you calculations are written as desired to speed things up.
Use Java 8's lambda-function to build something behaving similar to for-loops where you can null-out the counter for the rest of the cycle (actually this is a variant of #2)
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* Created for http://stackoverflow.com/q/25423743/1266906
*/
public class LambdaLoops {
public static void main(String[] args) {
iterate(0, 42, (i) -> {
System.out.println("A-loop:" + (i + 0));
i = null;
});
iterate(0, (i) -> i < 42, (i) -> ++i, (i) -> {
System.out.println("B-loop:" + (i + 0));
i = null;
});
iterate(0, (i) -> i < 42, (i) -> {
System.out.println("C-loop1:" + (i + 0));
i = null;
// Next statement will not throw an Exception
System.out.println("C-loop2:" + i);
// Next statement will throw an Exception
System.out.println("C-loop3:" + (i + 0));
});
}
static void iterate(Integer initial, Integer limit, Consumer<? super Integer> function) {
for (Integer i = initial; i < limit; i++) {
function.accept(i);
}
}
static void iterate(Integer initial, Predicate<? super Integer> when, Consumer<? super Integer> function) {
for (Integer i = initial; when.test(i); i++) {
function.accept(i);
}
}
static <T> void iterate(T initial, Predicate<? super T> when, Function<? super T, ? extends T> increment, Consumer<? super T> function) {
for (T i = initial; when.test(i); i = increment.apply(i)) {
function.accept(i);
}
}
}
as in #3 this will most likely lead to decreased performance, but has the advantage, that your IDE might alert you, that i will always be null. This should however be easier to optimize be inlining than #3 as there is no additional boolean involved. If and when the JIT does inlining is however hard to guess.
Since so many of answers talk about why this is a bad idea, so I won't repeat it.
One solution that comes to my mind is to use an counter object. Whenever you want a particular counter to go out of scope, set that to null. If you use it after this point, a Null pointer access warning is shown (at least in eclipse. I suspect other IDEs should also have this feature. Not sure whether javac generates a warning).
public class DisappearingVariables {
public static class Counter {
int i = 0;
public Counter() {
}
public void inc() {
i++;
}
public int get() {
return i;
}
}
public static void main(String[] args) {
for(Counter i = new Counter(), oi = i; i.get() < 10; i = oi, i.inc()) {
System.out.println("i = " + i.get());
i = null;
i.inc(); // This line gets a warning
for(int j = 0; j < 10; j++) {
}
}
}
}

Exception in thread "Thread-2" java.lang.NullPointerException.error in my code

I had my code working (at least somewhat) and I must have changed something, because now it won't even launch. There's no shown errors within the code, but when I try to run it this is what appears:
Exception in thread "Thread-2" java.lang.NullPointerException
at azsystem3.Add.run(Main.java:57)
at java.lang.Thread.run(Thread.java:662)
and (Main.java:57) is this line: sum.s+=a[i];
How do I fix it?
Here's my relevant code:
package azsystem3;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Fill implements Runnable{
int []a;
static Random b = new Random();
int start;
int end;
public Fill(int[]a,int start,int end){
this.a=a;
this.start=start;
this.end=end;
}
public void run(){
for(int i=this.start;i<this.end;i++){
a[i]=b.nextInt(100);
}
}
}
class value{
int s;
}
class Add implements Runnable{
value sum;
Lock L ;
int[]a;
int start;
int end;
//public long sum=0;
public Add(int[]a,int start, int end,Lock L,value s){
this.L=L;
this.start=start;
this.end=end;
sum=s;
}
public void run(){
int i;
for( i=start;i<end;i++)
L.lock();
sum.s+=a[i];
L.unlock();
}
}
class main {
public static void main(String[] args) {
value sum=new value();
Lock Lock=new ReentrantLock();
int[] array = new int[100000];
Scanner sc=new Scanner (System.in);
System.out.println ("Enter number : ");
int n = sc.nextInt();
int tmp = 100000 / n;
Thread[] t = new Thread[n];
for (int i = 0; i < n; i++) {
t[i] = new Thread(new Fill(array, (i) * tmp, (i + 1) * tmp));
t[i].start();
}
for (int i = 0; i < n; i++) {
try {
t[i].join();
} catch (InterruptedException exception) {
}
}
Thread[] t1 = new Thread[n];
Add[] add = new Add[n];
long start = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
add[i] = new Add(array, (i) * tmp, (i + 1) * tmp,Lock,sum);
t1[i] = new Thread(add[i]);
t1[i].start();
}
for (int i = 0; i < n; i++) {
try {
t1[i].join();
} catch (InterruptedException exception) {
}
}
long end = System.currentTimeMillis();
System.out.println("sum : " + sum);
System.out.println("time : " + (end - start) + "ms");
}
}
Any suggestions?
Thread-safety does not only requires locking on run()-method in your code, but you should also make your private members of class Add, especially the sum member, final. Otherwise a Thread might see a not fully initialized object of type value where the sum-member is still null.
And note: Please try to follow standard Java code conventions for better readability.
Another observation, this code
for( i=start;i<end;i++) // missing opening bracket {
L.lock();
sum.s+=a[i];
L.unlock(); // missing closing bracket }
is equivalent to:
for( i=start;i<end;i++) {
L.lock();
}
sum.s+=a[i];
L.unlock();
I have no trust in any thread-safety here because of improper handling of brackets and therefore locking.
While it looks like a thread-safety issue, the reason for the NullPointerException is quite simple:
In the constructor for the Add class you forgot to assign the int array instance variable a, i.e. a simple this.a=a; is missing.
That’s a reason why you should declare every instance variable as final whenever possible. Then the compiler will tell you about every missing value assignment.
Of course, you will have to fix the missing braces in the Add.run() method as well as otherwise you will get a dead-lock. In your case only the first thread threw a NullPointerException while all other threads were waiting forever.

Synchronizing a crowd in Java

I'm writing a demo program to explain how to regulate the concurrency of a crowd of threads in Java, but the result is not as I expected. This is the code:
package parcountSyncStat;
public class Parcount extends Thread {
private static int N=1000;
private static Integer x=0;
public static void main(String[] args) throws InterruptedException {
Thread[] t = new Thread[N];
int i;
for (i = N-1; i >= 0; i--) {
t[i]=new Parcount();
t[i].start();
}
for ( i=N-1; i>=0; i-- ) t[i].join();
System.out.println(x);
}
public void run() { synchronized(x) { x++; } }
}
In a nutshell, 1000 threads try to increment the same integer x. To preserve consistency, I encacsulate the increment in a synchronized block. The parent thread waits for all processes to finish, and then prints the final value of x, which should be 1000. But it isn't. My question is: why? I'm I wrong somewhere?
Note that I obtain the expected result by implementing a class that encapsulates the integer with a synchronized "Increment" method. But replacing the synchronized with a lock/unlock pair does not work either. I'm using Eclipse and did try both openjdk and oracle jdk, with similar results.
Thanks
x++ creates a new Integer object - so every time you run that statement the lock used becomes different. If you want one single lock for all you thread, create an ad hoc object:
private static final Object lock = new Object();
and synchronize on that lock.
Thanks to assylias: here is the complete code:
public class Parcount extends Thread {
private static int N=1000;
private static Integer x=0;
private static final Object lock = new Object();
public static void main(String[] args)
throws InterruptedException {
Thread[] t = new Thread[N];
int i;
for ( i=N-1; i>=0; i-- ) {
t[i]=new Parcount();
t[i].start();
}
for ( i=N-1; i>=0; i-- ) t[i].join();
System.out.println(x);
}
public void run() { synchronized(lock) { x++; } }
}
The following code uses the owner of your shared resource x, the class Example, as the instance to synchronize with. You may try changing your code like this:
public class Example extends Thread {
public static void main(String[] args) throws InterruptedException {
Thread[] t = new Thread[N];
for (int i = N - 1; i >= 0; i--) {
t[i] = new Example();
t[i].start();
}
for (int i = N - 1; i >= 0; i--) t[i].join();
System.out.println(x);
}
private static int N = 1000;
private static int x = 0;
#Override public void run() {
synchronized (Example.class) { x++; }
}
}

Categories

Resources