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.
Related
I'm pretty confused about some java behavior, especially because my previous understanding of java was that it was strictly pass-by-value.
If I pass an object to a method, then null that object in the calling thread, I would expect the object would still exist and be able to be operated on in the method, but this is not the case.
Here is some sample code:
public class methodTest {
boolean bool;
boolean secondBool;
Test list;
public static void main(String[] args) {
new methodTest().run();
}
public void run() {
list = new Test();
new Thread(() -> {
func(list);
}).start();
list = null;
bool = true;
while (!secondBool) {
// block
}
System.gc();
}
public void func(Test big) {
while (!bool) {
// block
}
System.out.println(big);
secondBool = true;
}
class Test {
#Override
protected void finalize() throws Throwable {
System.out.println("I'm getting cleaned up!");
}
#Override
public String toString() {
return "Test!";
}
}
}
This code prints
null
I'm getting cleaned up!
when I would expect it to print:
Test!
I'm getting cleaned up!
I included the garbage collection call at the end and the finalize method in the class to ensure that the gc wasn't getting to the variable list before the function could print it, but the same effect occurs without it.
What is the explanation for this behavior?
EDIT:
Another example of this would be if you changed the list = null line in the run method to list = new Test(), then slightly modified the toString to count the number of Test instances. The program would print "Test2" instead of "Test1", because the value of the parameter in func was overridden in the calling thread, even though in my understanding of java's pass-by-value system, this should not happen.
It prints null because there is a race condition and the new thread loses most of the time.
The timing is like this:
the main thread (the one running methodTest.run()) creates a new Thread object and starts the new thread (meaning it creates a new linux/windows thread and notifies it that it can start running)
as the very next step it sets the instance variable list to null
in parallel to the step 2 above the second thread starts running and eventually reaches the lambda () -> { func(list); }
only when the second thread executes func(list); will it read the instance variable list
What is passed as parameter big into func therefore entirely depends on
how much time the main thread needs to execute list = null;
how much time the os needs to start executing the second thread and for the second thread to reach the point where it calls func(list);
From your observation the second thread needs more time to reach the point where func(list); is executed than the main thread needs to execute list = null;
If I remember Java correctly, it changes the value for user defined classes. So if you use primitive data types and already defined classes like int, string, etc then it wont cause you this problem. But here you are using your own class so its passed by reference for some reason.
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'm learning for OCJP and now I'm at "Thread" chapter, I have some questions about wait and notify methods. I think I understand what's happening here but I just want to make sure that I'm on the right way.I wrote this code as an example:
package threads;
public class Main {
static Object lock = new Object();
public static void main(String[] args) {
new Main().new FirstThread().start();
new Main().new SecondThread().start();
}
class FirstThread extends Thread {
public void run() {
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
}
}
class SecondThread extends Thread {
public void run() {
synchronized (lock) {
try {
lock.wait();
System.out.println("I'm in the second thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In this example the console output is I've entered in FirstThread, because the first thread starts, the notify() method is called, then the second thread starts, the wait() method is called and the String "I'm in the second thread" is not printed.
The next scenario is that I reverse the positions of new Main().new FirstThread().start(); and new Main().new SecondThread().start(); the output is
I've entered in FirstThread
I'm in the second thread
because the second thread starts, the wait() method is called, then the first thread starts, the method notify() is called, the console prints I've entered in FirstThread, the wait is released and I'm in the second thread is printed in the console.
Is that happening because the computer is so fast and the threads run sequentially? Theoretically the second start() method can be called first in my opinion is it?.
And the last question I have, is why the lock Object must be static, because if I remove the static modifier the output is always I've entered in FirstThread?
I know that static fields are loaded in JVM when the class is loaded, but I can't understand the logic of lock Object.
The threads are started sequentially, and in theory thread 1 would execute before thread 2, although it's not guaranteed (pretty sure it'll be consistent in this simple case though, as there are no real or simulated aleatory delays).
This is why when thread 2 is started slightly before, it has a chance to wait on a lock that gets notified (by thread 1) subsequently, instead of waiting forever for a lock that's already been notified once (hence, no printing).
On the static lock Object: you're binding your [First/Second]Thread nested classes to instances of Main, so the lock has to be common to both if you want them to synchronize on the same lock.
If it was an instance object, your threads would access and synchronize on a different lock, as your new Main()... idiom would get two instances of Main and subsequently two instances of lock.
"Is that happening because the computer is so fast and the threads run
sequentially? Theoretically the second start() method can be called
first in my opinion is it?. "
Yes, you can introduce a sleep() with random time, for better (unit-) test, or demonstration purpose. (Of course, the final running code should not have that sleep)
And the last question I have, is why the lock Object must be static
Principally, it does not matter whether the lock is static or not, but you have to have the possibility to access it, and it must be the same lock object. (Not one object instance for each class). In your case it must be static, otherwise it would be two different objects instances.
This is wrong because it doesn't change any shared state that the other thread can test:
synchronized (lock) {
lock.notify();
System.out.println("I've entered in FirstThread");
}
And this is wrong because it does not test anything:
synchronized (lock) {
lock.wait();
System.out.println("I'm in the second thread");
}
The problem is, lock.notify() does not do anything at all if there is no thread sleeping in lock.wait(). In your program, it is possible for the FirstThread to call notify() before the SecondThread calls wait(). The wait() call will never return in that case because the notify() call will do nothing in that case.
There's a reason why they make you enter a mutex (i.e., a synchronized block) before you can call wait() or notify(). It's because you are supposed to use the mutex to protect the shared shared state for which the waiter is waiting.
"shared state" can be as simple as a single boolean:
boolean firstThreadRan = false;
The notifier (a.k.a., "producer") does this:
synchronized(lock) {
firstThreadRan = true;
lock.notify();
...
}
The waiter (a.k.a., "consumer") does this:
synchronized(lock) {
while (! firstThreadRan) {
lock.wait();
}
...
}
The while loop is not strictly necessary in this case, but it becomes very important when more than one consumer is competing for the same event. It's good practice to always use a loop.
See https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html for a tutorial that explains wait() and notify() in more detail.
I was wondering if it was okay that you give a thread access to an instance of a class
so you can perform operations on certain members/variables of that class.
For example, I have both a main thread and a thread.
I'm giving the second thread access to the instance of the main class
so I can perform an operation on x.
However, what if at some point in the future I decide to do operations on x
in the main thread? Or just simply reading from x. What if both the other thread and the main
thread want to read x at the same time?
Is this at all okay by the way I have it structured in my code to do?
package test;
import java.lang.Thread;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class AThread extends Thread {
Test test;
AThread(Test test) {
this.test = test;
}
BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
public void run() {
String msg;
while ((msg = queue.poll()) != null) {
// Process the message
//System.out.println(msg); //should print "hello"
if (msg.equals("up")) {
test.setX(test.getX()+1);
System.out.println(test.getX());
}
}
}
}
public class Test {
AThread aThread;
private int x = 5;
void setX(int x){
this.x = x;
}
int getX(){
return x;
}
Test() throws InterruptedException{
System.out.println("MainThread");
aThread = new AThread(this);
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
public static void main(String[] args) throws InterruptedException {
new Test();
}
}
And not just the member 'x', but also there could be more members in class "Test" that I'd want to be able to perform operations on such as reading/writing.
Is this an okay structure to do so? If not, what should be fixed?
There are several problems with your code.
Consider this line:
aThread = new AThread(this);
It is always a bad idea to pass this somewhere in a constructor. And this has nothing to do with the threads... yet. The reason is that the 'somewhere' may call a method on this, and the method could be overridden in a subclass whose constructor wasn't called yet, and it may end up in disaster because that override may use some of the subclass fields that aren't initialized yet.
Now, when threads come into the picture, things get even worse. A thread is guaranteed to have correct access to a class instance that was created before the thread is started. But in your case, it isn't created yet, because the constructor is not finished yet! And it's not going to finish anywhere soon because of the infinite loop below:
while (true) {
aThread.queue.put("up");
}
So you have an object creation running in parallel to a startup of a thread. Java doesn't guarantee that the thread will see the initialized class in such case (even if there was no loop).
This is also one of the reasons why starting threads in constructors is considered a bad idea. Some IDEs even give a warning in such cases. Note that running infinite loops in constructors is probably a bad idea too.
If you move your code into a run() kind of method and do new Test().run() in main(), then you code will look fine, but you are right to worry about
However, what if at some point in the future I decide to do operations
on x in the main thread?
The best idea is for the main thread to forget about the object right after it is passed to the thread:
public static void main(String[] args) throws InterruptedException {
AThread aThread = new AThread(new Test());
aThread.start();
while (true) {
aThread.queue.put("up");
}
}
However, what if at some point in the future I decide to do operations on x in the main thread? Or just simply reading from x. What if both the other thread and the main thread want to read x at the same time?
Any time you are sharing information between two threads, you need to provide for memory synchronization. In this case, if you make int x be volatile int x then your code should work fine. You should read the Java tutorial on the subject.
However, if the thread is doing more complex operations, as opposed to just setting or getting x, then you may need to make the method be synchronized or otherwise provide a mutex lock to make sure that the 2 threads don't overlap improperly.
For example, if you need to increment the value of x, a volatile won't help since increment is actually 3 operations: get, increment, and set. You could use a synchronized lock to protect the ++ or you should consider using an AtomicInteger which handles incrementAndGet() methods in a thread-safe manner.
#Segey's answer gives some great feedback about the rest of your code. I'll add one comment about this code:
while (true) {
aThread.queue.put("up");
}
You almost never want to spin like this. If you want to do something like this then I'd add some Thread.sleep(10) or something to slow down the adding to the queue or make the queue bounded in size. It is likely that you are going to run out of memory spinning and creating queue elements like this.
I have a java applet. A class inside that applet is creating a thread to do some work, waiting 30 seconds for that work to complete, if its not completed in 30 secs it sets a Boolean to stop the thread. The wait and Boolean change are in a synchronized block, Is this necessary considering there is no other thread running aside from these 2.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
synchronized (_sessionThread)
{
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
}
Why couldn't I just do this instead.
System.out.println("Begin Start Session");
_sessionThread = new SessionThread();
_sessionThread.start();
_sessionThread.wait(30000);
_sessionThread._stopStartSession = true;
SessionThread run method. Invokes a JNI method to call a dll to open a program window.
public void run()
{
try
{
startExtraSession();
}
catch (Throwable t)
{
t.printStackTrace();
}
notify();
}
private native void openSessionWindow(String session_file);
private void startExtraSession()
{
final String method_name = "startExtraSession";
String title = _sessionInfo._title;
long hwnd = 0;
openSessionWindow(_sessionInfo._configFile);
try
{
//Look for a window with the predefined title name...
while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession)
{
Thread.sleep(500);
}
}
catch(Throwable t)
{
t.printStackTrace();
}
}
1. Is the synchronized really needed?
2. Is there a better way to accomplish this aside from using threads?
A given thread is required to own a lock on a object to be able to call wait(long) on it. This is achieved by using a synchronized block on the said object.
See J2SE specification on using wait.
Acquiring a lock/monitor in java can be done in various ways:
In a synchronized (non-static) method, the thread owns a monitor on the object referenced by this.
In a static synchronized method, the thread owns a monitor on the Class<?> descriptor for the class that defines the said method.
In a synchronized(x) block, the thread owns a monitor on x.
That lock will be released if:
You get outside of the synchronized code block (be it a method, static method, or explicit block).
You have called wait() or one of its variations (and you'll re-acquire it just before the method returns).
Both these two lists may omit specific cases but should cover at least a large portion of the typical use cases.
There's a very simple reason that you need synchronized to call wait
The synchronized makes sure that nobody is calling notify or notifyAll at the same time you're calling wait
For example: Thread 1
synchronized( obj )
{
triggerActionOnThread2();
obj.wait();
}
Thread 2 (triggered by triggerActionOnThread2)
...
synchronized( obj )
{
obj.notify();
}
If you don't have the synchronized blocks, then the notify might happen before (or during) the wait, and then the wait misses the notify, and you can hang Thread 1.
Imagine the above blocks of code without the synchronized blocks, and imagine if Thread 2 is executed all the way through the notify before the wait gets called.
BTW, I ask this very question on interviews for Java engineers when the job will involve multithreaded programming.
Can you please post SessionThread code? You cannot wait if you don't own the lock, so you need synchronized (_sessionThread) to do _sessionThread.wait(30000); Not sure what's with _sessionThread._stopStartSession = true;
If the boolean is the only shared state between the threads, declaring the boolean transient will guarantee that changes to it are seen between the threads as would a synchronization block around access to the boolean.