Java guarantees initialization safety for immutable objects? - java

To prove initialization safety for immutable objects, I wrote a small program. Even though fields were final, second thread was able to view the half-constructed object being created by the first thread. Have I got the concept wrong or "object escaping" can cause it? Second thread first printed "10 null" and then after half of the iterations it started printing "10 apple".
package test;
import java.util.ArrayList;
import java.util.List;
public final class ObjectEscape implements Runnable {
private final int a;
private final String b;
//this list is defined somewhere else
public static volatile List<ObjectEscape> globalList = new ArrayList<ObjectEscape>();
public ObjectEscape () throws InterruptedException {
a = 10;
globalList.add(this);
Thread.sleep(10);
b = "apple";
System.out.println("done");
}
public ObjectEscape(int a) {
this.a = 1;
b = "";
}
public static void main(String are[]) throws InterruptedException{
Thread t = new Thread(new ObjectEscape(1));
t.start();
ObjectEscape oe1 = new ObjectEscape();
}
#Override
public void run() {
int i=0;
while(i<10) {
if(globalList.get(0) != null)
System.out.println(globalList.get(0).a+" "+globalList.get(0).b);
i++;
}
}
}

final fields are guaranteed to have been initialized when the contructor call finishes. Naturally, a "leaking this" will subvert the value of this guarantee:
globalList.add(this); // ObjectEscape.<init> has not finished yet
See also: Java leaking this in constructor

Related

Unable to understand sync

Hey I am trying to make 10 threads in a synchronized manner and I came up with the code below however I am not able to understand a part of it as mentioned below. I am still really new to java, I tried looking up synchronized threading from
Here but still I am clueless.
class question3 {
public static void main(String arg[]) throws Exception {
for (int i = 0; i < 11; i++) {
data di = new data();
System.out.println(di.count);
}
}
}
class item {
static int count = 0;
}
class data extends item implements Runnable {
item d = this;
Thread t;
data() {
t = new Thread(this);
t.start();
}
public void run() {
d = syn.increment(d);
}
}
class syn {
synchronized static item increment(item i) {
i.count++;
return (i);
}
}
I am not sure what this part of code does?
public void run() {
d = syn.increment(d);
}
}
class syn {
synchronized static item increment(item i) {
i.count++;
return (i);
}
}
the run function is used when starting the thread, this is a must function you need to override when implement Runnable. When calling Thread.start(), the run function will be called.
The class syn contains a synchronized method, it is simply mean that only one thread can access it each time, thus make the incerment function thread safe.
object d has a static variable count meaning all instances of item class (and data ) share the same count, so all threads increment the same variable
the line d = syn.increment(d); is basically count++ but in a thread safe way

Affecting variables in different classes in Java

I have two classes that I'm trying to manipulate one variable with, as an example
public class A {
public static void main(String[] args) {
while(game_over[0] == false) {
System.out.println("in the while-loop");
}
System.out.println("out of the while-loop");
}
static boolean[] game_over = {false};
}
and
public class B {
public boolean[] game_over;
public printBoard(boolean[] game_over) {
this.game_over = game_over;
}
public void run() {
for (int i = 0; i < 10; i++) {
// do something
}
game_over[0] = true;
System.out.println("GAME OVER");
}
}
The code snippets provided are not meant to be actual workable code, I'm more concerned with the concept. In my program, class A creates a thread that utilizes class B, and I want class B to affect the variable 'game_over' such that the while-loop in class A will be affected by the change... any idea how I can successfully update the variable? Thanks.
Don't use an array for this, that makes it harder to ensure a data-race free application.
Since you want to be able to pass around the game_over flag as an independent object, the easiest way to achieve a correct multi-threaded application is to use the AtomicBoolean class.
import java.util.concurrent.atomic.AtomicBoolean;
class B {
private AtomicBoolean game_over;
public B(AtomicBoolean game_over) {
this.game_over = game_over;
}
public void run() {
// do stuff
game_over.set(true);
}
}
and in your class A:
public class A {
static AtomicBoolean game_over = new AtomicBoolean();
public static void main(String[] args) {
B b = new B();
Thread t = new Thread(b);
t.start();
while (!game_over.get()) {
System.out.println("in the while-loop");
}
System.out.println("out of the while-loop");
}
}

List populated in different thread appears empty in caller thread - Java

My code basically goes like this:
//in Main Thread: (myList is a volatile field)
myList = new ArrayList<myClass>();
Thread myThread = new Thread(new MyCustomRunnable(myList));
myThread.start();
//some lines of code NOT involving myList
myThread.join();
//myList appears empty here even though I can see that the list has been populated
//in the other thread
Is there a reason for this behavior? Like I said, i can see in the debugger that the list has been populated in the called thread, but these changes don't appear in the caller thread after the join() method. MyCustomRunnable also declares the ArrayList as a volatile field, assigned by the constructor.
UPDATE:
Ok, I made a simpler program, replacing the ArrayList with a simple Integer and the results are the same...
public class Threading {
private volatile static Integer i = 0;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new MyCustomRunnable(i));
t.start();
t.join();
System.out.println(i); //prints '0', I expected '1'
}
}
public class MyCustomRunnable implements Runnable {
private volatile Integer i;
public MyCustomRunnable(Integer i) {
this.i = i;
}
public void run() {
this.i = 1;
}
}
Why isn't the Integer's value updated in the main Thread?
Add
public static void setI(int i) {
Threading.i = i;
}
to your Threading class and in your runnable add
public void run() {
this.i = 1;
Threading.setI(1);
}
This has nothing to do with multithreading, just variable scoping. i in the Threading class is not updated in MyCustomRunnable's run method.

java: Passing a class reference to another thread

I'm trying to learn how to use multithreading in Java. I have a main and two classes which extend Thread, A and B. I want the main to start A, which makes multiple calls to B. Once A is finished, I want B to send something to main.
The main creates two threads, one A and one B, and then starts both threads. A does something, which will then pass on a result to B. The main then collects an answer from B and does something else. I don't know how to get the total from B back to the main.
I'm also not sure how to instantiate the two classes (threads) but then give A a reference of B since Java uses pass-by-value. Can someone give me some pointers.
public static void main(String[] args)
{
B b = new B();
A a = new A(100, b);
B.start();
A.start();
A.join(); // Waiting for A to die
// Here I want to get a total from B, but I'm not sure how to go about doing that
}
public class A extends Thread
{
private int start;
// Some reference to B
B b;
public A (int n, B b) {
int start = n;
this.b = b;
}
public void run() {
for (int i = 0; i < n; i++) {
b.add(i);
}
}
}
public class B extends Thread
{
private int total;
public B () {
total = 0;
}
public void add(int i) {
total += i;
}
}
I changed your example code into what I consider to be a more meaningful example.
Communication between threads is usually handled through shared data (or channels like pipes, sockets - but I wont go there...). And while it is perfectly alright to have this shared data contained within the thread classes I have seperated the shared data from the data/methods used to administer the threads.
I hope this helps you to understand the relationship between threads and data objects.
public class TestThreads {
public static void main(String[] args)
{
DataShare ds = new DataShare();
B b = new B(ds);
A a = new A(100, ds);
b.start();
a.start();
try {
a.join(); // Waiting for A to die
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println ("Accumulated total from B = " + b.getTotal());
b.endThread();
}
}
public class DataShare {
private int value;
public DataShare () {
value = -1;
}
public synchronized boolean setValue(int val) {
boolean valueSet = false;
if (value == -1) {
value = val;
valueSet = true;
}
return valueSet;
}
public synchronized int getValue() {
int val = value;
value = -1;
return val;
}
}
public class A extends Thread {
private int max;
private DataShare dataShare;
public A (int n, DataShare ds) {
max = n;
dataShare = ds;
}
public void run() {
int i = 0;
while (i < max) {
if (dataShare.setValue(i)) {
i++;
}
}
}
}
public class B extends Thread {
private int total;
private DataShare dataShare;
private boolean running = false;
public B (DataShare ds) {
dataShare = ds;
total = 0;
}
public void run() {
running = true;
while (running) {
int nextValue = dataShare.getValue();
if (nextValue != -1) {
total += nextValue;
}
}
}
public int getTotal() {
return total;
}
public synchronized void endThread() {
running = false;
}
}
I am aware that this naive example is far from optimal since both threads are wasting precious cycles while waiting for the value to be set/read. I just wanted to keep the example as simple as possible while still addressing the point I'm trying to make.
A decent way to do it. You just pass an instance of class A:
public class Foo {
public void doFoo() {..} // that's the method you want to use
}
public class Bar {
private Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public void doSomething() {
foo.doFoo(); // here you are using it.
}
}
And then you can have:
Foo foo = new Foo();
Bar bar = new Bar(foo);
bar.doSomething();
First of all, B should not be a thread. If all it does is respond to messages from A, then it can just be an object like any other.
Second, while everyone says java uses pass by value, the confusing part is that object references are passed by value, so objects are effectively passed by reference. Thus, you can pass B to A, and get the total from your copy of B.
If we look at your code:
B b = new B();
A a = new A(100, b);
B.start();
A.start();
A.join(); // Waiting for A to die
// Here I want to get a total from B, but I'm not sure how to go about doing that
You are passing a pointer of b to A. That means that if class A only accesses class B directly (it does not replace it with a new instance of B) that the object should contain anything that class A did to it. In other words, both your main code and class A work on the same object of B. So you should be able to get the total of b simply by asking the object you have instantiated in main.
So if you call
b.total();
at the end of main, it should return your value (of course you must ensure that thread A will not make changes to it after retrieving the value).
I assume that you are trying to achieve communication between the two threads you create in the main method. This is, however, not happening. I made a few changes to your code and included it below to show what I think you wanted to do.
First, a few corrections of your examples:
You cannot use class names (A and B) when referencing thread objects as you do in the main method. Use the object names instead (a and b).
In class A constructor you are creating a new local variable start instead of referencing the member variable. Hence: int start = n should be start = n
I'm guessing you want to loop the number of times set in constructor. Hence for (int i = 0; i < n; i++) { should be for (int i = 0; i < start; i++) {
Pass by reference/value is not really relevant here. Object references are passed by value as anything else is. It is, however, the contents of the reference variable (the object address) which is interesting and that will not change. In other words, when passing an object reference to a method, the method WILL address that specific object, and any change made to the contents of the objects will be visible outside the method as well.
Here are your examples with a few corrections as I think you intended them.
public class TestThreads {
public static void main(String[] args)
{
B b = new B();
A a = new A(100, b);
b.start();
a.start();
try {
a.join(); // Waiting for A to die
} catch (InterruptedException e) {
e.printStackTrace();
}
// Getting a total from b is simple, if you provide the method for it
System.out.println ("Accumulated total from B = " + b.getTotal());
}
}
public class A extends Thread {
private int start;
// Some reference to B
B b;
public A (int n, B b) {
start = n;
this.b = b;
}
public void run() {
for (int i = 0; i < start; i++) {
b.add(i);
}
}
}
public class B extends Thread {
private int total;
public B () {
total = 0;
}
public void add(int i) {
total += i;
}
public int getTotal() {
return total;
}
}
Now, here is the problem with these examples:
An object is not a thread and vice versa. In the main thread (lets call that thread tM) You are creating an object of class B and forking a new thread (thread tB) starting in its run() method. However, since you did not override the run method, the threat ends immediately after creation.
Then you create an object of class A. Gives it the reference to object b (which has nothing to do with thread tB) and fork a new thread (thread tA). Here you did implement a run() method. The result is the following:
Thread tM did the initial work and is now waiting for thread tA to finish.
Thread tB was started and died immediately afterwards
Thread tA is doing all the work of incrementing the counter of object a, and making object b add the counter to its sum.
When tA finished after 100 increments tM wakes up and acquires the sum from object b (which again has nothing to do with thread tB).

How to demonstrate race conditions around values that aren't published properly?

I am reading "Java Concurrency in practice" and looking at the example code on page 51.
According to the book this piece of code is at risk of of failure if it has not been published properly. Because I like to code examples and break them to prove how they work. I have tried to make it throw an AssertionError but have failed. (Leading me to my previous question)
Can anyone post sample code so that an AssertionError is thrown? Rule: Do not modify the Holder class.
public class Holder{
private int n;
public Holder(int n){
this.n = n;
}
public void assertSanity(){
if (n != n) {
throw new AssertionError("This statement is false");
}
}
}
I have modified the class to make it more fragile but I still can not get an AssertionError thrown.
class Holder2 {
private int n;
private int n2;
public Holder2(int n) throws InterruptedException{
this.n = n;
Thread.sleep(200);
this.n2 = n;
}
public void assertSanity(){
if (n != n2) {
throw new AssertionError("This statement is false");
}
}
}
Is it possible to make either of the above classes throw an AssertionError? Or do we have to accept that they may occasionally do so and we can't write code to prove it?
I'd run this on a multiprocessor machine for a few hours and see what happens(remove the sleep if you use your Holder2). Such race conditions might be rare, or not existant on your particular machine - but atleast try to provoke these one on a million cases , by trying millions of times.
class Checker {
private Holder h;
public Checker() {
h = new Holder(42);
}
public void check() {
h.assertSanity();
}
public void create(int n) {
h = new Holder(n);
}
}
public class MyThread extends thread{
private bool check;
private final Checker c;
public MyThread(bool check,Checker c) {
this.check = check;
this.c = c;
}
public static void main(String[] args) {
Checker c = new Checker();
MyThread t1 = new MyThread(false,c);
MyThread t2 = new MyThread(true,c);
t1.start();
t2.start();
t1.join();
t2.join();
}
public void run() {
int n = 0;
while(true) {
if(check)
c.check();
else
c.create(n++);
}
}
}
}
As BobbyShaftoe said in the other thread, you can't rely on just running the code enough times to show that the error can or cannot happen. If you think about this from an Assembly level, it will be very hard for n != n as it is so few calls and relies on the process being switched out at a really precise time.
If you want to be able to show whether a concurrent system is provably valid it would be better to model it using something like Labelled Transition Systems. Try the LTSA tool if you're interested in proving concurrency or finding errors.
http://www.doc.ic.ac.uk/ltsa/
In the example the that book is giving the Holder class is not directly the cause of the problem, in fact it states that:
The problem here is not the Holder class itself, but that the Holder is not properly published. However, Holder can be made immune to improper publication by declaring the n field to be final, which would make Holder immutable; see Section 3.5.2.
Just prior to this it mentions the following code, which it the subject of the problem:
// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
So to re-create it you will need to create a publisher class and two threads, one that calls initialize and one that calls the assert.
Having said that, I tried to re-create it myself and still failed to do so :(
Below is my first attempt, however there is a better explanation of the problem at http://forums.oracle.com/forums/thread.jspa?threadID=1140814&tstart=195
public class HolderTest {
#Test
public void testHolder() throws Exception {
for (int i = 0; i < 1000000000; i++) {
final CountDownLatch finished = new CountDownLatch(2);
final HolderPublisher publisher = new HolderPublisher();
final Thread publisherThread = new Thread(new Publisher(publisher,
finished));
final Thread checkerThread = new Thread(new Checker(publisher,
finished));
publisher.holder = null;
publisherThread.start();
checkerThread.start();
finished.await();
}
}
static class Publisher implements Runnable {
private final CountDownLatch finished;
private final HolderPublisher publisher;
public Publisher(final HolderPublisher publisher,
final CountDownLatch finished) {
this.publisher = publisher;
this.finished = finished;
}
#Override
public void run() {
try {
publisher.initialize();
} finally {
finished.countDown();
}
}
}
static class Checker implements Runnable {
private final CountDownLatch finished;
private final HolderPublisher publisher;
public Checker(final HolderPublisher publisher,
final CountDownLatch finished) {
this.publisher = publisher;
this.finished = finished;
}
#Override
public void run() {
try {
publisher.holder.assertSanity();
} catch (final NullPointerException e) {
// This isnt the error we are interested in so swallow it
} finally {
finished.countDown();
}
}
}
static class HolderPublisher {
// Unsafe publication
public Holder holder;
public void initialize() {
holder = new Holder(42);
}
}
}
I don't think the assertion error can occur without modifying the Holder class. I think the book is wrong.
The only reason to cause the assertion error is when assertSanity() is called on a partially constructed object. How can a thread, other than the constructor thread, reference a partially constructed object? AFAIK, it's only possible in the following two cases:
Publish this in the constructor. E.g. assign this to a shared variable. This can't happen in our sample code because Holder's constructor doesn't do that.
A class's non-static inner class can refer to its parent even when its parent is partially constructed. This can't happen either because Holder doesn't have any inner class.
Note that the following code in the book doesn't publish any partially constructed object:
public class GoodCode {
public Holder holder;
public void initialize () {
holder = new Holder(42);
}
}
If you disassemble initialize(), you get the following:
public void initialize();
Code:
0: aload_0
1: new #2 // class Holder
4: dup
5: bipush 42
7: invokespecial #3 // Method Holder."<init>":(I)V
10: putfield #4 // Field holder:LHolder;
13: return
Note that putfield holder executes after invokespecial <init>. This means the assignment of holder happens after the constructor is completed. The partially constructed object is only stored in the thread's stack. It's not published.
If you can trigger the assertion error in a reasonable way (e.g. reflection is not reasonable), put it here. I will up vote you.
You cant change value of n at any time by using:
Holder h = new Holder(5);
Field f = h.getClass().getDeclaredField("n");
f.setAccessible(true);
f.setInt(h, 10);
h.assertSanity();

Categories