A thread moves from the Runnable state to the Running state as the result of being executed by the thread scheduler.
The
scheduling of Java threads is performed in an operating system-specific manner. In general, threads with a higher
thread priority are scheduled before threads of a lower priority.
Thread priority may be accessed via the
setPriority()
and
getPriority()
methods of the
Thread
class. Most operating systems that you will deal with use one of the following scheduling algorithms:
- preemptive scheduling (Solaris) - The highest priority thread continues to execute until it enters the waiting or dead states, or a higher priority thread comes into existence.
- time slicing (Windows, MacOS) - A thread executes for a specific slice of time and then enters the ready state. The thread scheduler then selects another (possibly the same) thread to execute.
Because Java does not require a specific scheduling algorithm, you cannot predict the order in which threads will be scheduled.
Moving from Runnable to Running requires a thread to be scheduled. A thread may easily move from Running to Runnable by invoking its yield()
method.
By doing so, a thread tells the scheduler that it is willing to take a break while other ready threads execute.
In systems where preemptive scheduling is used, the yield()
method can prevent high-priority threads from monopolizing processing resources.
What will happen when the class WaitTest is run using the command line:
java WaitTest a c b
import java.util.*;
public class WaitTest {
public static void main(String[] args) {
new AnotherThread(args).start(); //1
synchronized (args) {
try {
args.wait();
} catch (InterruptedException e) { }
List< String> m = Arrays.asList(args);
System.out.println(m);
}// end -synchronized
}// end -main
}
class AnotherThread extends Thread {
String[] args;
AnotherThread(String[] sa) {
args = sa;
}
public void run() {
synchronized (args) {
List<String> m = Arrays.asList(args);
Collections.sort(m);
args.notifyAll();
}
}
}
Select 3 options:
- It MAY print [a, b, c].
- It MAY print [a, c, b].
- It MAY print nothing.
- It will NEVER print [a, c, b].
- It will not compile.
- It may print the elements of the args array in any order.
- It will throw an exception at runtime.
Answer: a, c, d
Explanation:
e. There is no problem with the code.
There are two things in the program:
1. JVM may schedule any thread to run at any time. In this case, if the main thread is suspended at line //1 and AnotherThread gets to run, it will enter the
synchronized block, sort the List m,
call
notifyAll()
and terminate. Now, the main thread will run and enter the
synchronized block. It will call
args.wait();
and start waiting on somebody to call
notifyAll()
on args.
However, there is no other thread that will call
notifyAll()
because AnotherThread has already terminated and its call to
notifyAll()
has already been lost. So the main thread will keep on waiting forever without printing anything. Thus, option 3 is correct. Now consider the situation where the main thread gets to run first. It will enter the
synchronized block and will start waiting. Now, AnotherThread will run, sort the list and call
notifyAll()
, thereby awaking the main thread. The main thread will dump the contents of the args array and the program will terminate.
2. The
Arrays.asList()
method creates a List representation of the array. So any changes made to the list is actually reflected in the array.
Thus, when the main thread prints the array, it will always be sorted (because AnotherThread sorted it already). Therefore option 1 and 4 are correct.