I am curious if the following code is thread-safe:
public static void methodA () {
// given that mutableObject is not thread-safe (no lock/synchronization used)
MutableObject mo = new MutableObject();
mo.setSomeValue(100); // set an int value
// the mutableList variable must be final in order to pass it to the thread block
final List<mutableObject> mutableList = new ArrayList<mutableObject>();
mutableList.add(mo);
Thread t = new Thread() {
#Override
public void run() {
for (mutableObject e : mutableList) {
e.printIntValue(); // print 100 or 0?
}
}
}
t.start();
}
so, here is the question.
I am not sure whether all contents reachable* from the "mutableList" reference are visible to the new thread even though there is no explicit synchronization/locking used. (visibility issue) In other words, would the new thread print 0 or 100? it would print 0 if it does not see the value 100 set by the main thread as 0 is the default primitive value of the int data type.
ie. "contents reachable" means:
the int value 100 which is held by the MutableObject
the reference to the MutableObject held by the ArrayList
Thanks for answering.
This code is thread-safe because there is not way that any other thread will access the same objects because they are available inside methodA() and in method run() of your thread. Both do not change the data.
Thread safety problems appear when at least 2 threads operate the same data. This is not your case.
How to make you code thread-unsafe?
There are several ways.
add line mo.setSomeValue(100); after calling t.start(). This means that after staring the thread there are 2 threads (your main thread and your other thread) that operate the same object mo. This will no however cause exceptions.
add line mutableList.remove(0). This may cause ConcurrentModificationException if your thread starts quickly enough and manages to enter the loop before main thread arrives to remove instruction.
There is no question of thread safety here.
The objects mo and mutableList are both defined and instantiated within the function call. Each time the function is called 2 new objects (above) are being created. No thread-unsafe values whatsoever.
Related
Imagine that we have multithreading application and a class with the following variable and method:
private List list = new ArrayList();
public void doNothing() {
synchronized (list) {
list.get(0);
String stuff = "Stuff";
list.get(0);
}
}
Am I right that when one thread processes method doNothing() it loses monitor on String stuff = "Stuff"; and the output of list.get(0); may be different because other thread can modify the list?
Yes, you are right, but not because the monitor is lost on handling the stuff string. The fact that you synchronized on the list does not prevent another thread to change it. The only way to enforce the list being unchanged between the two gets is to have all threads changing the list run that code inside a synchronized(list). Also, having a Synchronized list will not help in your case.
Only one thread at a time can work in synchronized block. But if any other thread modifies the list in for example some other function then of course, output of list.get(0) can differ between invocations. String stuff due to being created in this block can't be changed by any other thread than the one that is currently running through it.
Only one thread can execute inside a Java code block synchronized on the same monitor object.
The thread only "loses the monitor" once it reaches the end of the synchronized block.
In your specific case, the result from calling list.get(0); can be the same or not, depending on other threads that can invoke the mutators on that list outside any code block synchronized on the list object.
The purpose of the synchronization objects is to allow you to synchronize more than one block on the same lock.
In the following example only one thread can execute inside any of the two blocks at the same time:
public void doNothing() {
synchronized (list) {
//someStuff
}
}
public void doSomething() {
synchronized (list) {
//anotherStuff
}
}
I was told, that creating a new instance is always an async message; but I don't understand why.
e.g.:
Foo myFoo = new Foo();
Here I will have to wait until the constructor finishes and returns my new object. But doesn't asynchronous mean, that I go on independently (no waiting) - like starting a thread?
I was told, that creating a new instance is always an async message;
Sorry, I have to say that either you heard it wrong or you were told something that is wrong. But first off, we should get some terminology straight. The term "async" or "asynchronous" means that the invocation returns immediately to the caller. We can easily demonstrate that this is not true with a constructor, with a simple experiment [1]. In other words, the constructor must return for the caller to make any progress.
Starting a thread is indeed asynchronous. The call to Thread.start() returns immediately and at some later point in time the thread actually starts running and executing the run() method.
1 The Experiment
Consider your class (for illustration only) is like below:
Foo.java
class Foo {
Foo() throws InterruptedException {
while (true) {
System.out.println("not returning yet ...");
Thread.sleep(2000);
}
}
public static void main(String[] args) throws InterruptedException {
Foo foo = new Foo();
}
}
If you compiled and run this class (I used Java 8 on my Mac, but that is not a requirement). As expected, this class runs forever producing the output every 2 seconds:
not returning yet ...
not returning yet ...
not returning yet ...
not returning yet ...
Note that the sleep call was added just to make it bearable. You could try this experiment without it, but then your program will overwhelm one of the CPU's by stressing it to 100%.
If, while it is running, you took a thread dump (for example, by using the command jstack), you see something like below (curtailed for brevity):
"main" #1 prio=5 os_prio=31 tid=0x00007f9522803000 nid=0xf07
waiting on condition [0x000000010408f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
Regardless of the state of the thread (RUNNABLE, BLOCKED, WAITING, TIMED_WAITING), you will always see (take various thread dumps to see what this means) you will always see these two lines:
at Foo.<init>(Foo.java:5)
at Foo.main(Foo.java:9)
which means that the caller (in this case, the main thread) will never make any progress. And since this constructor never returns, no progress happens.
I was told, that creating a new instance is always an async message;
No, java constructors doesn't have implyed synchronization. Anyway, you can have concurrency issues within it. There is not guarantee that all the fields are initialized after the constructor call.
Here I will have to wait until the constructor finishes and returns my new object. But doesn't asynchronous mean, that I go on independently (no waiting) - like starting a thread?
Nope, you don't have to wait. You can access the object within another thread.
I suggest you to read this thread.
Example for concurrent access to an object while the constructor is still executing:
public class Demo {
private volatile int constructionCounter;
private volatile String string;
public Demo() throws InterruptedException {
super();
assert this.constructionCounter == 0;
this.constructionCounter++;
// From this point on, there's no way the constructionCounter can ever be != 1 again, because the constructor will never run more than once, concurrently or otherwise.
assert this.constructionCounter == 1;
final Demo newInstance = this;
Thread t = new Thread( new Runnable() {
public void run() {
// Access new instance from another thread.
// Race condition here; may print "Hello null" or "Hello World" depending on whether or not the constructor already finished.
System.out.println("Hello " + newInstance.getString());
}
});
t.start();
this.setString( "World!" );
}
public String setString( String str ) {
this.string = str;
}
public String getString() {
return this.string;
}
}
Note that this is only ever possible if and when the constructor itself somehow hands this out to another thread.
so I got this horses race and when a horse getting to the finishing line, I invoke an arrival method. Let's say I got 10 threads, one for each horse, and the first horse who arrives indeed invoking 'arrive':
public class FinishingLine {
List arrivals;
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public synchronized void arrive(Horse hourse) {
arrivals.add(hourse);
}
}
Ofc I set the arrive method to synchronized but I dont completely understand what could happen if it wasnt synchronized, the professor just said it wouldn't be safe.
Another thing that I would like to understand better is how it is decided which thread will after the first one has been finished? After the first thread finished 'arrive' and the method get unlocked, which thread will run next?
1) It is undefined what the behaviour would be, but you should assume that it is not what you would want it to do in any way that you can rely upon.
If two threads try to add at the same time, you might get both elements added (in either order), only one element added, or maybe even neither.
The pertinent quote from the Javadoc is:
Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.)
2) This is down to how the OS schedules the threads. There is no guarantee of "fairness" (execution in arrival order) for regular synchronized blocks, although there are certain classes (Semaphore is one) which give you the choice of a fair execution order.
e.g. you can implement a fair execution order by using a Semaphore:
public class FinishingLine {
List arrivals;
final Semaphore semaphore = new Semaphore(1, true);
public FinishingLine() {
arrivals = new ArrayList<Horse>();
}
public void arrive(Horse hourse) {
semaphore.acquire();
try {
arrivals.add(hourse);
} finally {
semaphore.release();
}
}
}
However, it would be easier to do this with a fair blocking queue, which handles the concurrent access for you:
public class FinishingLine {
final BlockingQueue queue = new ArrayBlockingQueue(NUM_HORSES, true);
public void arrive(Horse hourse) {
queue.add(hourse);
}
}
There are two things that I did not clear, one concerns the new operator, the other, the method Thread.sleep.
// Create a second thread.
class NewThread implements Runnable {
Thread t;
NewThread() {
// Create a new, second thread
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for the second thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println("Child Thread: " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
System.out.println("Exiting child thread.");
}
}
class ThreadDemo {
public static void main(String args[]) {
new NewThread(); // create a new thread
try {
for(int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
I know that the new operator is used to allocate an object
for example: Box refvar=new Box(); call the constructor of Box class
in this case the call is new NewThread();
But I have no reference variable, I don't understand how Java call the constructor without reference variable. Normally I use: Nameofclass reference-variable-name = new NameOfConstructor();.
Another thing I do not understand is: how Java can call Thread.sleep() if there is no object with the name Thread? in this case should be: t.sleep(1000) or not?
Thanks in advance.
You can call a constructor without assigning a reference to it.
In your case, the field Thread t maintains a reference to the thread, so there will be no premature garbage collection.
Thread.sleep() sleeps the current thread; i.e. the thread that is currently executing that bit of code.
It is valid to create an object (new File()) without storing the object (File file = new File()). In that case you create the object and call the constructor but can't do anything with the result. In many cases this doesn't do much (but it could change static data or throw an exception).
In your case the constructor NewThread() actually creates a thread and starts it.
Your second question regarding Thread.sleep() actually calls the static function sleep in the class Thread, which will wait for the given time and then return. So this will actually sleep the current thread, and not another thread that you call it on. Note that even calling it on a thread object (someThread.sleep()) still sleeps the current thread and not someThread. In your example the current thread is the main thread (which is created by the JVM and eventually used to call the main function)
new NewThread();
Creates a new object with no reference in your main, therefore after the creation you are no more able to access this object within main. But the object is created anyway.
Thread.sleep(1000);
Secondly, sleep is a static method, therefore you can call this method directly with the classname, you do not need to instanciate an object of thread first for this.
Thread.sleep(...)
is possible because sleep is a static method which
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to the
precision and accuracy of system timers and schedulers.
according to the JavaDoc
1) new ClassName() will create an instance. Even if you can't refer to it later, you can call instance methods on that instance there itself.
2) Thread class has a static method called sleep() and static method doesn't require an instance. They can directly be called using the className.methodName()
Thread#sleep always affects only the current thread. You are not allowed to target other threads in order to put them to sleep. Calling t.sleep() results in the static method being called, which affects the current thread. Calling static methods on an instance is a bad idea, it is likely to mislead people who read the code into thinking the code is putting another thread to sleep.
Your NewThread creates a thread in the constructor. Once you start a thread it will run until it terminates, regardless of if anything else has a reference to it. Each thread is a GC root that prevents garbage collection of anything that it references. Keeping a reference to the thread would allow you to interrupt it or otherwise communicate with it.
The posted code looks like it was created by somebody who had heard that using Runnable was preferred over extending Thread, but who had missed the point about why. Having a Runnable create a thread for itself defeats the purpose of separating Runnables (the tasks that need to be executed) from the means of executing the tasks (the threads). This is not a good way to design any real code for a purpose other than causing confusion.
Generally Thread Created 2-way,
1. extends Thread class
2. implements Runnable interface.
Here, you have choose option-2, e.g. Runnable Interface.
In your code,
you have first Created new Thread(...) with new keyword, which is wrap-in Runnable object inside it.
Answer-2 :
Thread.sleep() method : it's pause current thread's execution, while executing it, current thread move to Wait/Block state from Running State of thread life-cycle.
After completion of N-millisecond (here 500, i.e. 0.5 sec.).
that thread again wake up it and comes to Runnable state.
Let me know, if still any query.
I understood synchronization of a block of code means that particular code will be accessed by only one thread at time even many thread are waiting to access that.
when we are writing thread class in run method we starting synchronized block by giving object.
for example
class MyThread extends Thread{
String sa;
public MyThread(String s){
sa=s;
}
public void run(){
synchronized(sa){
if(sa.equals("notdone"){
//do some thing on object
}
}
}
}
here we gave sa object to synchronized block what is the need of that.any how we are going to provide synchronization for that particular block of code
I would suggest
extend Runnable rather than Thread.
don't lock in the Runnable on an external. Instead you should be calling a method which may use an internal lock.
String is not a good choice as a lock. It means that "hi" and "hi" will share a lock but new String("hi") will not.
if you are locking all other threads for the life of the thread, why are you using multiple threads?
The parameter object of the synchronized block is the object on which the block locks.
Thus all synchronized blocks with the same object are excluding each other's (and all synchronized methods' of this same object) simultaneous execution.
So if you have this example
class ExampleA extends Thread() {
public ExampleA(Object l) {
this.x = l;
}
private Object x;
public void run() {
synchronized(x) { // <-- synchronized-block A
// do something
}
}
}
class ExampleB extends Thread() {
public ExampleB(Object l) {
this.x = l;
}
private Object x;
public void run() {
synchronized(x) { // <-- synchronized-block B
// do something else
}
}
}
Object o1 = new Object();
Object o2 = new Object();
Thread eA1 = new ExampleA(o1);
Thread eA2 = new ExampleA(o2);
Thread eB1 = new ExampleB(o1);
Thread eB2 = new ExampleB(o2);
eA1.start(); eA2.start(); eB1.start(); eB2.start();
Now we have two synchronized blocks (A and B, in classes ExampleA and ExampleB), and we have two lock objects (o1 and o2).
If we now look at the simultaneous execution, we can see that:
A1 can be executed in parallel to A2 and B2, but not to B1.
A2 can be executed in parallel to A1 and B1, but not to B2.
B1 can be executed in parallel to A2 and B2, but not to A1.
B2 can be executed in parallel to A1 and B1, but not to A2.
Thus, the synchronization depends only on the parameter object, not on the choice of synchronization block.
In your example, you are using this:
synchronized(sa){
if(sa.equals("notdone"){
//do some thing on object
}
}
This looks like you try to avoid that someone changes your instance variable sa to another string while you are comparing it and working - but it does not avoid this.
Synchronization does not work on a variable, it works on an object - and the object in question should usually be either some object which contains the variable (the current MyThread object in your case, reachable by this), or a special object used just for synchronization, and which is not changed.
As Peter Lawrey said, String objects usually are bad choices for synchronization locks, since all equal String literals are the same object (i.e. would exclude each other's synchronized blocks), while a equal non-literal string (e.g. created at runtime) is not the same object, and thus would not exclude synchronized blocks by other such objects or literals, which often leads to subtle bugs.
All threads synchronized on this objects will wait until current thread finishes its work. This is useful for example if you have read/write operation to collection that your wish to synchronized. So you can write sychronized block in methods set and get. In this case if one thread is reading information not all other threads that want to either read or write will wait.
So the question is what is the function of the object that a block synchronizes on?
All instances of Object have what is called a monitor. In normal execution this monitor is unowned.
A thread wishing to enter a synchronized block must take possession of the object monitor. Only one thread can posses the monitor at a time, however. So, if the monitor is currently unowned, the thread takes possession and executes the synchronized block of code. The thread releases the monitor when it leaves the synchronized block.
If the monitor is currently owned, then the thread needing to enter the synchronized block must wait for the monitor to be freed so it can take ownership and enter the block. More than one thread can be waiting and if so, then only one will be given ownership of the monitor. The rest will go back to waiting.