Java - Accessing Static Method Sleep - What's wrong? - java

When I put the code below in NetBeans, NetBeans gives me a warning next to it saying "Accessing static method sleep".
try {
Thread.currentThread().sleep(2000);
}
catch(InterruptedException ie){
//continue
}
Am I doing something wrong? Should I be calling this differently? I'm not doing anything multi-threaded. I just have a simple main method that which I want to sleep for a while.

Thread.currentThread() returns an instance of the Thread class. When invoking a static method you only want to work on the class itself. So invoking a static method on current thread you will get a warning you are calling the method on an instance.
You would just call Thread.sleep(2000); It would be equivalent to Thread.currentThread.sleep(2000);
This is important to know because people have been burned doing something like:
Thread a = new Thread(someRunnable);
a.start();
a.sleep(2000); //this will sleep the current thread NOT a.
Edit: So how do we sleep a? You sleep a by writing the sleep invocation within the runnable passed in to the constructor, like:
Runnable someRunnable = new Runnable(){
public void run(){
Thread.sleep(2000);
}
};
When 'a' is started, Thread.currentThread in someRunnable's run method is the 'a' thread instance.

sleep is static, so you access it with Thread.sleep(2000);. It affects the current thread.
From the javadoc:
Causes the currently executing thread
to sleep (temporarily cease execution)
for the specified number of
milliseconds. The thread does not lose
ownership of any monitors.
What that means is that you can't sleep another thread, only the one that the code is in.

Thats because the sleep() method is declared as static therefore
Thread.currentThread().sleep(2000);
is the same as
Thread.sleep(2000);

There is no method on Thread instances that corresponds to "sleep(long)".
Thread.currentThread().sleep(2000); does compile, however, because there is a method on the thread class that is called sleep() with a long argument.
Java allows this as a compiler time trick so that new coders could execute this when they are confused about the static access of methods.
However, what this actually is resolved to in the compiler is:
Thread.sleep(2000);
The following code is also equivalent:
Thread t = new Thread(new Runnable() { public void run() { // do nothing } });
t.sleep(2000);
As one poster (John V) has pointed out, this doesn't make the actual thread (t) instance sleep - the current thread that created the thread object is put to sleep.
The warning exists such that you remember that you're accessing a static method of a class, not a method of an instance variable.
The appropriate code to write is always Thread.sleep(2000); - never access static methods through an instance to avoid confusion and this warning.

netbeans giving you warning because you are accessing static method from Thread reference not from Thread class.
try this
try {
Thread.sleep(2000);
}
catch(InterruptedException ie){
//continue
}
sleep method Causes the currently executing thread to sleep.So no need to call Thread.currentThread().

Whenever you try to access static method using object it is not best practise, NB gives warning at that time, here is the same case
Thread.currentThread() will return you a object of Thread

Related

Using methods inside a thread

When I try to use methods inside a class in which I extend Thread it does not receive the methods after the run.
My class:
public class PassPhraseValidator<E> extends Thread {
private List<E> list;
private boolean isValid;
private String passPhrase;
public PassPhraseValidator(List<E> list) {
this.list = list;
}
public String getPassPhrase() {
return passPhrase;
}
public boolean isValid() {
return isValid;
}
public void run(){
this.passPhrase = Arrays.toString(list.toArray());
this.isValid = list.stream().filter(e -> Collections.frequency(list, e) > 1).count() == 0;
}
}
So when I execute this class like this:
PassPhraseValidator<Integer> validIntegerPassPhrase = new PassPhraseValidator<>(Arrays.asList(12, 18, 15, 32));
validIntegerPassPhrase.start();
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
It gives me false while it should be true because the run function wasn't ran yet.
What am I doing wrong here? How can I make multithreading part of this? It does work when I directly put it inside the methods.
The last System.out.println statement does not wait for your thread (the run function) to complete.
One way to wait for its completion is to call the join method
validIntegerPassPhrase.join(); //Need to handle the InterruptedException it might throw
System.out.println(validIntegerPassPhrase.getPassPhrase() + " valid: " + validIntegerPassPhrase.isValid());
Explanation
What you are doing is called multithreading. This allows multiple threads to execute code concurrency or in parallel. Programs run on something called the main thread. This means one thread is executing all code systematically; one instruction after another. When introducing another thread like you are, the program execution is being done on different logic at the same time. So, when you execute the start() method on your implementation of the thread class, you are causing it to execute it's respective run() method in the background until; it completes, an exception is thrown, the application is shutdown, or the thread is stopped.
Lets step through your code and analyze the scenario.
Thread object is instantiated by the main thread. Lets call this new thread thread2.
thread2 is started by the main thread.
thread2 and the main thread are both running in parallel. This means code is being executed by both of them (for simplicity) at the same time.
Two possibilities could be occurring for this issue; Java Memory Barrier (beyond the scope of this question but more reference here) or timing. The main thread is most likely reading the print statement before thread2 can finish it's respective run() method.
Solution
An approach may be not to use multi-threading at all. The creation of threads is quite a costly operation and should not be done frequently. Typically, in app's that require multi-threading thread-pools are utilized instead.
Utilize the join() blocking function. Join forces the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation.
Implement the thread with use of Promise. This object is a wrapper for the Future class, allowing for the get() method to be blocking. This means the calling thread (in this case it would be the main thread) to wait for the respective thread to finish execution before continuation. An example of Promise's can be found here.

Calling java timer in a synchronized block of codes

If I have a parent block of codes called A, A is synchronized. And in A, I executes a child block of code called B. Am I right to assume that B will be synchronized also?
If in A I have a timer to delay the execution of B in a certain of t time, is there a chance that B gets executed later when A already finished?
Thank you very much.
P/S: Sorry the the unclear code, this is how it should look like
synchronized A{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
B block
}
}, 2*60*1000);
}
Depends. If the block B is a block of code within method like this, then yes... it will be synchronized.
public synchronized void methodA() {
// Block B
{
// some code
}
}
If it's another method like the following, then no:
public synchronized void methodA() {
methodB();
}
public void methodB() {
// Block B code
// Nothing prevents an unsynchronized method from calling this method
// at same time as methodA() holds lock on `this` object
}
Unless methodB is also marked synchronized or called from another synchronized method (eg/ public synchronized methodC()) or another synchronization mechanism is used, then methodB() is not synchronized.
Those are just the simplest cases. You're better off posting example code since 'block' is not well defined by default and the type of synchronization lock (implicit on this via synchronized method vs. explicit object lock) makes a difference.
But, your last line sounds like you're asking about synchronous vs. asynchronous execution of code which, while related to threading and synchronized blocks, is a different concept.
In that case, it depends on what happens in block A ... if new threads are created to execute block B then anything can happen with the timing of code execution. If no threads are created, it's safe to assume that block A will not complete before block B.
Edit: based on code now posted ... the synchronized A block will only ensure the Timer threads get created one at a time. But, unless there's something special about the Java Timer framework, there's nothing there that will prevent two threads from executing the B block in the run method simultaneously ... so make sure that the contents are thread safe.
That is, don't assume that just because different instances of Timer are created in a synchronized block with the same delay, they won't get into the run method at the same time. If the B block accesses external un-thread-safe code (eg. static methods, disk access), you could have surprises.
As Amm Sokun mentioned in other answer, A{} will return before
Block B executes.
Block B will be executed after A has finished executing, this is because in method A you are just scheduling B to be run after 2*60*1000 milli, and timer will take care of executing B after 2*60*1000 milli

How do java.lang.Thread static methods work?

E.g. method public static void sleep(long millis). This method causes current thread to sleep, but how does it know, which thread is current? Static methods are object-independent and belong to class, so how does this mechanism work?
This method causes current thread to sleep, but how does it know, which thread is current?
The current thread is managed by the underlying operating system (or the threading system). The underlying (system dependant) thread implementation provides a handle to the current thread:
In case of POSIX threads, there is the API call pthread_self() which returns the thread ID of the currently executing thread. You can think of Thread.currentThread() eventually calling this C function and wrap the thread ID in a Java Thread object which is then returned.
In case of MS Windows, there is the API call GetCurrentThread() which returns the Windows Handle of the currently executing thread. Again, you can think of Thread.currentThread() eventually calling this C function and wrap the Handle in a Java Thread object which is returned.
native methods are special. They have access beyond the Java API.
In this case, to the current thread. You can't use this method to put another thread to sleep - the other thread will have to do this by itself (but you can send it a message, obviously).
This method is always called for the current / executing thread.
It means your current thread will go in sleep mode for a perticlar time.
Ex: if i will write Thread.sleep(1000) thread will go to sleep state for 1000 miliseconds.
We use this menthod mainly to interchange between the thread.In short, it will give chance to another thread for execution.
The current thread is the one actually executing the piece of code. As simple as that.
For instance:
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
System.out.println("Before sleeping!");
Thread.sleep(10000);
System.out.println("After sleeping!");
}
}
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
System.out.println("Main thread!");
}
May output something like:
Before sleeping! // t1
Main thread! // main
Before sleeping! // t2
After sleeping! // t1
After sleeping! // t2

Instance variable and new thread

Why does the below program output 11 and not 12?.
Does not the thread use the same instance variables? Please explain?
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
The above code compiles fine. i is defaulted to 0 value on construction of object.
In happens before relation concept all code executed prior to start of thread is completed.
The concept is - instance variables are shared across multiple threads - here there are two threads running - the main thread and the Tester thread. So i should shared with both threads? - if i is shared and if happens-before relation is maintained before starting Tester thread then the value of incremented i should be visible to the Tester thread?
Give to your new thread the time to increase the variable, try with
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
try {
Thread.sleep(1000); // 1 sec
} catch (Exception ex) {}
System.out.println(t.i);
}
The only problem in your code is that you print the t.i value and do not wait after t.start(), you print the value before the thread increases it.
The instance variable can be accessed by multiple threads if you let them, for example making it public, or by any other means.
In your code this is what happens: The Tester thread t will access it's own variable, and you will access also that same variable from the main thread. For the moment when you ask it to print the value, it may print any value by which the Testet thread t is at the moment.
When the main thread calls the run method it will execute in the main thread, effectively increasing the value of the field to 1 (as 0 is the default). Afterwards when you call the method start it will start the separate thread and the Java VM will call the method run, then again the field gets incremented, this time from 1 to 2.
So, I would expect that the output is 1 and then, possible 1 or possibly 2 depending on whatever there was time for the thread to execute before you asked to print the value from the main thread.... the exact result you get depends on your machine, in another computer it can be another tale. This depends on the CPU, the operating system, the available memory and other things.
As dash1e suggested in his answer, you can use Thread.sleep(1000); to make the main thread wait while the Tester thread t executes on background. This greatly increases the likelihood that the Tester thread t will have updated the value of the field before the main thread asks for it to print it. That said, I want to left clear that using Thread.sleep(1000); to wait for a task to complete is not good enough by itself... if you want to, you can put a call to Thread.sleep inside a while where you verify if a certain criteria has been met, that's known as an spinning.
The fact that you can print the value of the field form the main thread demostrates that you can access it from another thread. And that is a good thing, because you want your thread to communicate... somehow.
It is ok to access it because it is only an int, and an int cannot be in an invalid state, so there is no need sync the access. Although you may get an not up-to-date value, and it will change on background, so it isn't very reliable.
If you want a value that can only be acceded by a single thread, and that exists idependly for each thread, then take a look to ThreadLocal.
The main answer that I was looking for was in terms of happens-before: Concept detailed below:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html#MemoryVisibility
So it says in the docs -
a) that before a thread starts - all statements prior to it are completed
b) all statements in the thread execution are completed at the termination of the new thread.
Going with the above understanding - i should be all the time visible to the new thread started. And this it should be - at all times, on all systems - so when start is called and a new thread is launched then it should always see i as 1.
But, the time we are printing the i value is getting executed by the main thread - not by the Tester thread. So even though the new Tester thread may see the value as 1 and increment it as 2 - the execution in main does not reflect it because i++ is not an atomic operation.
Now suppose we try and make the int as :
private volatile int i;
volatile guarantees happens-before relationship for not only the specific variable but also statement until it.
The println of main thread that gets executed may get executed before the increment even began. So we may see 11 getting printed, even after making the variable volatile. Similar case exists for making the variable an AtomicInteger.
The run method when invoked will see the incremented value:
System.out.println("i "+ i.incrementAndGet());
But not the main thread. Visibility of data in the run method / main method differs.
Instance variable used is same for both threads executing.
You have started the thread, but have not wait for it to stop. Use t.join() to wait for finish. And, yes, you have thread synchronization issue, but that's another issue.
public class Tester extends Thread {
private int i;
public static void main(String[] args) throws InterruptedException {
Tester t = new Tester();
t.run();
System.out.println(t.i);
t.start();
t.join();
System.out.println(t.i);
}
public void run() {
i++;
}
}
I your code:
public class Tester extends Thread {
private int i;
public static void main(String[] args){
Tester t = new Tester();
t.run();
System.out.print(t.i);
t.start();
System.out.print(t.i);
}
public void run(){ i++;}
}
You call t.run() and t.start(). There are 2 thread are running t.run() thread and t.start() thread.
In that i variable you share between 2 thread that is not synchronous.
Therefore sometime value of i variable is not update between threads.
You can synchronous by using volatile keyword
private volatile int i;
Or synchronise code segment increases value of i
public void run(){
synchronized(this){
i++;
}
}

Does Java notify waiting threads implicitly?

I wrote a test app that should never stop. It issues t.wait() (t is a Thread object), but I never call notify. Why does this code end?
Despite the main thread synchronizing on t, the spawned thread runs, so it doesn't lock this object.
public class ThreadWait {
public static void main(String sArgs[]) throws InterruptedException {
System.out.println("hello");
Thread t = new MyThread();
synchronized (t) {
t.start();
Thread.sleep(5000);
t.wait();
java.lang.System.out.println("main done");
}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
java.lang.System.out.println("" + i);
try {
Thread.sleep(500);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
The result is that the main thread waits 5 seconds and during this time worker gives its output. Then after 5 seconds are finished, the program exits. t.wait() does not wait. If the main thread wouldn't sleep for 5 seconds (commenting this line), then t.wait() would actually wait until the worker finishes. Of course, join() is a method to use here, but, unexpectedly, wait() does the same thing as join(). Why?
Maybe the JVM sees that, since only one thread is running, there is no chance to notify the main thread and solves the deadlock. If this is true, is it a documented feature?
I'm testing on Windows XP, Java 6.
You're waiting on a Thread - and while most objects aren't implicitly notified, a Thread object is notified when the thread terminates. It's documented somewhere (I'm looking for it...) that you should not use wait/notify on Thread objects, as that's done internally.
This is a good example of why it's best practice to use a "private" object for synchronization (and wait/notify) - something which only your code knows about. I usually use something like:
private final Object lock = new Object();
(In general, however, it's cleaner to use some of the higher-level abstractions provided by java.util.concurrent if you can. As noted in comments, it's also a good idea to implement Runnable rather than extending Thread yourself.)
The JavaDoc for wait gives the answer: spurious wakeups are possible. This means the JVM is free to end a call to wait whenever it wants.
The documentation even gives you a solution if you don't want this (which is probably always the case): put the call to wait in a loop and check whether the condition you wait for has become true after every wakeup.

Categories

Resources