Synchronisation block does not work correctly - java

I'm trying to run the below code but can't get the correct output.
Expected Output
"welcome new programmer"
Actual output
"new welcome programmer"
class First {
public synchronized void display(String msg) {
System.out.print("["+msg);
System.out.println("]");
}
}
class Second {
String msg;
First fobj;
Second (First fp,String str) {
fobj = fp;
msg = str;
start();
}
public void run() {
synchronized(fobj) { //Synchronized block
fobj.display(msg);
}
}
}
public class SyncroBlock {
public static void main (String[] args) {
First fnew = new First();
Second ss = new Second(fnew, "welcome");
Second ss1 = new Second(fnew,"new");
Second ss2 = new Second(fnew, "programmer");
}
}
Where I did wrong here?
Can anyone correct me please?

Starting a thread from a constructor is a bad idea. It violates the principles of safe construction.
A common mistake that can let the this reference escape during construction is to start a thread from a constructor. When an object creates a thread from its constructor, it almost always shares its this reference with the new thread, either explicitly (by passing it to the constructor) or implicitly (because the Thread or Runnable is an inner class of the owning object). The new thread might then be able to see the owning object before it is fully constructed.
There’s nothing wrong with creating a thread in a constructor, but it is best not to start the thread immediately. Instead, expose a start or initialize method that starts the owned thread. Calling an overrideable instance method (one that is neither private nor final) from the constructor can also allow the this reference to escape.
3.2.1 Safe construction practices, Java Concurrency in Practice by Brian Goetz
Thread#start() call might take some time, so the expected "welcome -> "new" -> "programmer" actually can be in any order.
To do what you were planning, we need to make sure that the previous run() has started executing before you go to the next one. For my machine, a sleep for 100L between the calls was enough to get the right order.
Second ss = new Second(fnew, "welcome");
Thread.sleep(100L);
Second ss1 = new Second(fnew,"new");
Thread.sleep(100L);
Second ss2 = new Second(fnew, "programmer");
That isn't a good technique, you shouldn't utilise it like this. It makes execution sequential - we won't derive any benefits from multithreading.

I think you forget to implement Callable or Runnable or whatever you need for your Second class.

Related

Why would I check in a Runnable, that its Thread is not null?

I've found code like this in a project I'm taking over. I'm not sure, what the if condition is supposed to accomplish. If the Runnable is running, it does so in the Thread it checks for being null. So that is always the case, right?
public class Outer
{
Thread m_thread = null;
public Outer()
{
Runnable runner = new Runnable()
{
public void run()
{
if ( m_thread != null )
do_stuff();
}
};
m_thread = new Thread(runner);
m_thread.start();
}
}
There is actually another method, that sets m_thread to null, but since there is no loop in the runnable, does that make a difference? do_stuff() does not access m_thread.
Since m_thread is not marked volatile or guarded by any other memory barrier operation it's possible that when Runnable is running it will observe m_thread to be null. If do_stuff() requires non-null reference to m_thread, the code will fail.
Check the Safe Publication and Safe Initialization in Java article by Shipilev to understand safe publication idioms in Java. In short:
There are a few trivial ways to achieve safe publication:
Exchange the reference through a properly locked field (JLS 17.4.5)
Use static initializer to do the initializing stores (JLS 12.4)
Exchange the reference via a volatile field (JLS 17.4.5), or as the consequence of this rule, via the AtomicX classes
Initialize the value into a final field (JLS 17.5).
You don't. There was a fashion 20 years ago, that I think may have originated in a magazine, for run() methods to loop while (Thread.currentThread() != null). It was meaningless then and it is meaningless now, even when slightly re-expressed as in your code.
Simply spoken: that doesn't make any sense. When a line of code is executed in Java, some thread is running it.
Unless you start implementing your own tracking of threads, the fact that your code is running ... tells it that some thread is running it.
The code shown here A) violates Java naming conventions, and it also B) violates "common sense" in Java.
You see, you could still write code that first initializes that m_thread field, to then invoke runner.run() directly from the "main" thread. And the run method would find that the field is not null, and invoke doStuff(). If at all, you could check that Thread.getCurrentThread() returns something else than your "main" thread.
As in:
class Outer {
private Thread mainThread;
public Outer()
{
mainThread = Thread.getCurrentThread();
Runnable runner = new Runnable()
{
public void run()
{
if ( Thread.getCurrentThread() != mainThread )
do_stuff();
}
};
m_thread = new Thread(runner);
m_thread.start();
}
( I didn't run the above through the compiler, it is meant as "pseudo code like" example, not necessarily 100% correct )

Creating and naming multiple, simultaneous threads with a for loop

Is there a way to create multiple threads that run simultaneously with a for loop? Consider this example:
for(int i = 1; i<=36; i++) {
if(new Random().nextInt(2)==0){
ActionThread nr = new ActionThread();
}
}
I don't want the threads to be killed after completion of the if statement. The end of each thread is randomly determined in the ActionThread class itself. Also, how do I name the threads automatically? For example, instead of nr, the first thread should be named nr1, the second nr2, the third nr3, and so on.
I'm assuming that ActionThread is some custom class that you have created that extends Thread.
I don't want the threads to be killed after completion of the if statement.
They won't be. However, it doesn't look like you have started them yet. Read the javadocs for Thread. Read the material at the top, then look at the start() and run() methods.
If you don't start a thread ... nothing happens.
Also, if you want some other part of your application to be able to "do things" to the threads once they have been created, you should replace the nr local variable with a data structure that the the rest of the application can get at; e.g. a list or an array.
(It is also possible to find extant threads via the ThreadGroup tree, but it is complicated.)
Also, how do I name the threads automatically?
Call Thread.setName(), or pass the thread name to the (relevant) Thread constructor. For example:
nr.setName("thr" + i);
Or you could even make your ActionThread set its own name in the constructor.
I should also point out that is is generally considered to be a bad idea to create subclasses of Thread. It is better to put your thread logic into a custom Runnable class, then create and pass a Runnable instance as a Thread construct argument. Like this:
public class MyRunnable implements Runnable {
#Override
public void run() {
// thread logic goes here
}
}
Thread th = new Thread(new MyRunnable());
th.start();
If you want to pass parameters to the thread logic, add a constructor to your runnable class with some arguments, and provide them when you instantiate the runnable.
Why do it this way? Because it allows you to easily change your code to use a thread loop or executor or some such.
public static void main(String[] a) {
List<ActionThread> threads = new ArrayList<>();
for (int i = 1; i <= 36; i++) {
if (new Random().nextInt(2) == 0) { // no idea why you have put this
// but seems unecessary
ActionThread thread = new ActionThread();
threads.add(thread);
thread.start();
}
}
}
class ActionThread extends Thread {
#Override
public void run() {
// Write what to do in Thread here
}
}
Once the list of ActionThread is there you have handle to all the Threads that you have created. using threads.get(index). From question its appears that by name you meant handle to Thread instance
For automatic naming, may be use static field (counter) in ActionThread and increment him in the constructor, before generate thread name.
class ActionThread extend Thread {
private static int id = 0;
ActionThread() {
setName(String.format("n%d", ++id);
}
}

Java synchronized keyword issue

I am trying to understand the keyword synchronized from the following example
Java Main Method -->
public int methodA(){
Hello h = new Hello();
h.callSomeSynchronizedMethod();
sysout("Main");
return 0;
}
In the Hello Class-->
public synchronized void callSomeSynchronizedMethod(){
Hi h = new Hi();
h.someMethod();
sysout("Hello");
}
In the Hi class
public void someMethod(){
sysout("Hi");
}
So what would be the list of outputs that i will get;
1.) Is it in the order of Hi, Hello and Main ?
2.) What i understand about the synchronized keyword is that it will only execute 1 method and then execute the other, without multi-threading. Is this correct ?
To really understand what synchronized does you need to run the program twice, once synchronized and once not. Also your program should use multiple threads. So here is an example of such a test.
public class Synchro {
public static void main(String args[]){
new Synchro();
}
public Synchro(){
final Moo moo = new Moo();
Thread t = new Thread(new Runnable(){
public void run(){
moo.aMethod("Second");
}
});
t.start();//calling the method in a thread
moo.aMethod("First");//calling the same method from the same object in the main thread
}
class Moo{
public Moo(){
}
public void aMethod(String name){
//this loop just prints slowly so you can see the execution
for(int i = 1; i <= 100; i++){
System.out.println(String.format("%s : %d", name, i));
try{
Thread.sleep(50);
}catch(InterruptedException e){}
}
}
}
}
Now, if you run the above code, noticing that the method is not synchronized, you will see the printout from the two executions of the method interleaved. That is you will see First 1 then Second 1 then First 2 etc.
Now, add the synchronized keyword to the method making it:
public synchronized void aMethod(String name){ ....
and run the code again. This time, one execution of the method completes before the other begins.
The synchronized keyword is only necessary when multiple threads are accessing the very same object.
You would get "Hi", then "Hello", then "Main", yes. The synchronized modifier has nothing to do with the order the methods are called in; and, other than adding a bit of overhead, it does nothing at all when running the code in a single thread. You could run this same test without synchronized and get the same result.
Now, if you ran a similar test where multiple threads were calling these methods, your results would be less determinate.
Synchronized is meant to allow for the more safe execution of code and management of resources in a multi-threaded environment.
http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Hope this helps.
all these methods will be executed in one thread so the answer for the first question is "yes".
synchronized keyword emans that the method can be executed in only one thread at every moment of time. So if you call it from another thread - it will wait till the execution is finished in the first thread.
In Java there is no automatic multithreading: you must explicitly start a thread and pass it a run method that it will execute. Only in that case will the synchronized keyword start to matter, but its meaning is not quite as you understand it: the methods will execute in whatever thread calls them, but while one is executing, another thread will block before it is able to execute a method guarded by the same lock.

Starting a thread as the last statement of the constructor of a final class

I understand that in general it is a bad idea to start a new thread in a constructor because it could let this escape before it is fully constructed. For example:
public final class Test {
private final int value;
public Test(int value) throws InterruptedException {
start();
this.value = value;
}
private void start() throws InterruptedException {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Construction OK = " + Boolean.toString(Test.this.value == 5));
}
}).start();
}
}
public static void main(String[] args) throws InterruptedException {
Test test = new Test(5);
}
}
This prints (obviously not the same every run):
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = false
Construction OK = true
Construction OK = true
Construction OK = true
Now IF the start method is the last statement of the constructor AND reordering is prevented by using a synchronized block around the final value initialisation, is there still a risk associated with starting threads from the constructor?
public Test(int value) throws InterruptedException {
synchronized (new Object()) { // to prevent reordering + no deadlock risk
this.value = value;
}
start();
}
EDIT
I don't think this has been asked before in the sense that the question is more specific than just "Can I start threads in a constructor": the threads are started in the last statement of the constructor which means the object construction is finished (as far as I understand it).
Yes there is, because Test could be subclassed and then start() will be executed before the instance is created. The subclasses constructor may have something more to do.
So the class should be final at least.
In this particular case I would consider marking value as volatile (or use AtomicBoolean) and start the threads after the value is set:
this.value = value; // this.value.set(value) if using AtomicBoolean
start();
If going for this slightly dodgy solution, I would make the class final as well, to avoid the problem described by Andreas_D.
Regarding your edit:
[...] which means the object construction is finished (as far as I understand it).
That's right, but consider the following scenario:
Your test-threads are slightly more complex, and accesses a list testList of tests. Now if you do
testList.add(new Test());
the thread started in the constructor may not find the associated test in the list, because it has not yet been added. This is avoided by instead doing
Test t = new Test();
testList.add(t);
t.start();
Related question:
calling thread.start() within its own constructor
In the constructor you call the start method by
start()
of the class. Now you can notice that the method you are calling is of an object of this class which has not been create yet. So you are still passing a reference of an unconstructed object to a method. You have included the methodcall itself in the creation of the object, while any method of an object should be called after the object is constructed completely.
So still there is risk associated with it.
Also it was really a very good question.
The synchronized(new Object()) does NOT prevent reordering - because the monitor is a local variable, the compiler is actually free to ignore the synchronized block.
In particular, the compiler can prove that it is impossible that two threds would lock on the same monitor (by definition of local variables) and that the synchronized block is therefore redundant and can be ignored.

Using ThreadLocal in tandem with Volatile gives unpredictable results

I was reading through Java Memory model and was playing with volatile. I wanted to check how Volatile will work in tandem with ThreadLocal. As per definition ThreadLocal has its own, independently initialized copy of the variable whereas when you use volatile keyword then JVM guarantees that all writes and subsequent reads are done directly from the memory. Based on the high level definitions i knew what i was trying to do will give unpredictable results. But just out of curiosity wanted to ask if someone can explain in more details as if what is going on in the background. Here is my code for your reference...
public class MyMainClass {
public static void main(String[] args) throws InterruptedException {
ThreadLocal<MyClass> local = new ThreadLocal<>();
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(local.get());
thread.start();
}
}
}
public class MyClass implements Runnable {
private volatile boolean flag = false;
public void printNameTillFlagIsSet(){
if(!flag)
System.out.println("Flag is on for : " + Thread.currentThread().getName());
else
System.out.println("Flag is off for : " + Thread.currentThread().getName());
}
#Override
public void run() {
printNameTillFlagIsSet();
this.flag = true;
}
}
In your code you create a ThreadLocal reference as a local variable of your main method. You then store an instance of MyClass in it and then give that same reference of MyClass to 5 threads created in the main method.
The resulting output of the program is unpredictable since the threads are not synchronized against each other. At least one thread will see the flag as false the other four could see the flag as either true or false depending on how the thread execution is scheduled by the OS. It is possible that all 5 threads could see the flag as false, or 1 could see it false and 4 see it true or anything in between.
The use of a ThreadLocal has no impact on this run at all based on the way you are using it.
As most have pointed out you have deeply misunderstood ThreadLocal. This is how I would write it to be more accurate.
public class MyMainClass {
private static final ThreadLocal<MyClass> local = new ThreadLocal<>(){
public MyClass initialValue(){
return new MyClass();
}
}
public static void main(String[] args) throws InterruptedException {
local.set(new MyClass());
for(int i=0;i<5; i++){
Thread thread = new Thread(new Runnable(){
public void run(){
local.get().printNameTillFlagIsSet();
local.get().run();
local.get().printNameTillFlagIsSet();
}
});
thread.start();
}
}
}
So here five different instances of MyClass are created. Each thread will have their own accessible copy of each MyClass. That is Thread created at i = 0 will always have a different instance of MyClass then i = 1,2,3,4 despite how many local.get() are done.
The inner workings are a bit complicated but it can be done similar to
ConcurrentMap<Long,Thread> threadLocalMap =...;
public MyClass get(){
long id = Thread.currentThread().getId();
MyClass value = threadLocalMap.get(id);
if(value == null){
value = initialValue();
threadLocalMap.put(id,value);
}
return value;
}
To further answer your question about the volatile field. It is in essence useless here. Since the field itself is 'thread-local' there will be no ordering/memory issues that can occur.
Just don't divinize the JVM. ThreadLocal is a regular class. Inside it uses a map from current thread ID into an object instance. So that the same ThreadLocal variable could have its own value for each thread. That's all. Your variable exists only in the main thread, so it doesn't make any sence.
The volatile is something about java code optimization, It just stops all possible optimizations which allow avoid redundant memory reads/writes and execution sequence re-orderings. It is important for expecting some particular behaviour in multi-threaded environment.
You have two big problems:
1) As many pointed out, you are not using ThreadLocal properly so you don't actually have any "thread local" variables.
2) Your code is equivalent to:
MyClass someInstance = new Class();
for (...)
... new Thread(someInstance);
so you should expect to see 1 on and 4 off. However your code is badly synchronized, so you get random results. The problem is that although you declare flag as volatile, this is not enough for good synchronization since you do the check on flag in printNameTillFlagSet and then change the flag value just after that method call in run. There is a gap here where many threads can see the flag as true. You should check the flag value and change it within a synchronized block.
You main thread where you have a ThreadLocal object is being passed to all the threads. So the same instance is being passed.
So its as good as
new Thread(new MyClass());
What you could try is have an object being called by different threads with a thread local variable. This will be a proper test for ThreadLocal where each thread will get its own instance of the variable.

Categories

Resources