Showing posts with label Thread. Show all posts
Showing posts with label Thread. Show all posts

How do Java threads make the environment asynchrnous?


Ans: The thread mechanism in Java begins with the main entry point thread the runtime environment creates to start a Java program. When you use that initial thread create secondary threads, each one runs independently of the other. The Java virtual machine manages the execution of the threads so they behave as if they all run at the same time, in fact each thread briefly takes turns at execution.

In its simplest form there may be no communication or synchronization between multiple threads in a Java program and they each run to completion independently of each other. In this respect Java threads are fundamentally asynchronous, there is no master clock that governs when threads will run and when they synchronize variables to “catch-up” with each other.

It is often necessary and more useful if threads do check ready states before progressing, synchronize read and write access to shared variables and call-back to each other when their work is done. This is where the synchronized keyword and the various sleep(), wait() and notify() methods are used to more closely schedule the interaction between asynchronous threads.

What is difference between thread and process?


 Ans) Differences between threads and processes are:-
1. Threads share the address space of the process that  created it; processes have their own address.
2. Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
3. Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
4. Threads have almost no overhead; processes have considerable overhead.
5. New threads are easily created; new processes require duplication of the parent process.
6. Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
7. Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process do not affect child processes. 

Questions Related to Thread


Q:What’s the difference between Thread and Runnable types?
Ans: Java Thread controls the main path of execution in an application. When you invoke the Java Virtual Machine with the java command, it creates an implicit thread in which to execute the main method. The Thread class provides a mechanism for the first thread to start-up other threads to run in parallel with it.
The Runnable interface defines a type of class that can be run by a thread. The only method it requires is run, which makes the interface very easy to to fulfil by extending existing classes. A runnable class may have custom constructors and any number of other methods for configuration and manipulation.


Q: If all methods are synchronized, is a class thread safe?
Ans: Even if all the methods of a class are synchronized, it may still be vulnerable to thread safety problems if it exposes non-final fields or its methods return mutable object references that could be manipulated by multiple threads. Non-final fields should be declared private and encapsulated with synchronization. Rather than return references to internal object fields, create an independent copy that has no relation to the original, known as a deep copy.
A deep copy of an object duplicates the content and state of the original object and all its constituent fields in such a way that none of its properties refer to instances in the original at any level.
These measures will help prevent uncontrolled access to the internal state of objects, but you must also ensure synchronization techniques are applied in a robust, consistent manner that will not cause deadlock or race conditions. It is generally better to use synchronized blocks than synchronized methods for performance reasons. Limit the extent of synchronized blocks and ensure they all use the same object monitor.

Q: What's the difference between a thread's start() and run() methods?
Ans: The separate start() and run() methods in the Thread class provide two ways to create threaded programs. The start() method starts the execution of the new thread and calls the run() method. The start() method returns immediately and the new thread normally continues until the run()method returns.
The Thread class' run() method calls the run() method of the Runnable type class passed to its constructor. Subclasses of Thread should override the run() method with their own code to execute in the second thread.
Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method. Howevever, the code will only be executed in a new thread if the start() method is used.


Q: What is a Runnable object and a Runnable argument?
Ans: A Runnable object is one that implements the Runnable interface, which is the type used to execute new threads. The Runnable interface only has one method, run(), which must be implemented by a Runnable class.
In Java an argument is a primitive value or object reference that is passed to a constructor or method, defined in the method signature. A Runnable argument would be a constructor or method argument that is declared to be a Runnable type. The constructor of the Thread class is the most obvious example.
public Thread(Runnable target);
    
This constructor requires a Runnable type argument to be passed when a Thread is instantiated.


Q: What is a green thread?
Ans: A green thread refers to a mode of operation for the Java Virtual Machine (JVM) in which all code is executed in a single operating system thread. If a Java program has any concurrent threads, the JVM manages multi-threading behaviour internally rather than use additional operating system threads.
There is a significant processing overhead for the JVM to keep track of thread states and swap between them, so green thread mode has been deprecated and removed from more recent Java implementations. Current JVM implementations make more efficient use of native operating system threads. These days there is no case where the green thread approach is useful except on systems where this is the only concurrency scheme that is available for Java, on old operating systems and hardware platforms.


Q:What are the daemon threads? 
Ans: Daemon thread are service provider threads run in the background,these not used to run the application code generally.When all user threads(non-daemon threads) complete their execution the jvm exit the application whatever may be the state of the daemon threads. Jvm does not wait for the daemon threads to complete their execution if all user threads have completed their execution.
To create Daemon thread set the daemon value of Thread using setDaemon(boolean value) method. By default all the threads created by user are user thread. To check whether a thread is a Daemon thread or a user thread use isDaemon() method.
Example of the Daemon thread is the Garbage Collector run by jvm to reclaim the unused memory by the application. The Garbage collector code runs in a Daemon thread which terminates as all the user threads are done with their execution. 


Q:What happens if a start method is not invoked and the run method is directly invoked? 
Ans: If a thread has been instantiated but not started its is said to be in new state. Unless until a start() method is invoked on the instance of the thread, it will not said to be alive. If you do not call a start() method on the newly created thread instance thread is not considered to be alive. If the start() method is not invoked and the run() method is directly called on the Thread instance, the code inside the run() method will not run in a separate new thread but it will start running in the existing thread. 

ThreadGroup Class - Access Restriction Methods

The ThreadGroup class itself does not impose any access restrictions, such as allowing threads from one group to inspect or modify threads in a different group. Rather the Thread and ThreadGroup classes cooperate with security managers (subclasses of the SecurityManager class), which can impose access restrictions based on thread group membership.

The Thread and ThreadGroup class both have a method, checkAccess, which calls the current security manager's checkAccess method. The security manager decides whether to allow the access based on the group membership of the threads involved. If access is not allowed, the checkAccess method throws a SecurityException. Otherwise, checkAccess simply returns.

The following is a list of ThreadGroup methods that call ThreadGroup's checkAccess before performing the action of the method. These are what are known as regulated accesses, that is, accesses that must be approved by the security manager before they can be completed.
  • ThreadGroup(ThreadGroup parent, String name)
  • setDaemon(boolean isDaemon)
  • setMaxPriority(int maxPriority)
  • stop
  • suspend
  • resume
  • destroy
This is a list of the methods in the Thread class that call checkAccess before proceeding:
  • constructors that specify a thread group
  • stop
  • suspend
  • resume
  • setPriority(int priority)
  • setName(String name)
  • setDaemon(boolean isDaemon)
Related Posts:-

ThreadGroup Class- Methods that Operate on all Threads within a Group

The ThreadGroup class has three methods that allow you to modify the current state of all the threads within that group:

  • resume
  • stop
  • suspend
These methods apply the appropriate state change to every thread in the thread group and its subgroups.

Related Posts:-

ThreadGroup Class - Methods that Operate on the Group

The ThreadGroup class supports several attributes that are set and retrieved from the group as a whole. These attributes include the maximum priority that any thread within the group can have, whether the group is a "daemon" group, the name of the group, and the parent of the group.

The methods that get and set ThreadGroup attributes operate at the group level. They inspect or change the attribute on the ThreadGroup object, but do not affect any of the threads within the group. The following is a list of ThreadGroup methods that operate at the group level:
  • getMaxPriority and setMaxPriority
  • getDaemon and setDaemon
  • getName
  • getParent and parentOf
  • toString
For example, when you use setMaxPriority to change a group's maximum priority, you are only changing the attribute on the group object; you are not changing the priority of any of the threads within the group. Consider the following program that creates a group and a thread within that group:

class MaxPriorityTest {
public static void main(String[] args) {

ThreadGroup groupNORM = new ThreadGroup(
"A group with normal priority");
Thread priorityMAX = new Thread(groupNORM,
"A thread with maximum priority");

// set Thread's priority to max (10)
priorityMAX.setPriority(Thread.MAX_PRIORITY);

// set ThreadGroup's max priority to normal (5)
groupNORM.setMaxPriority(Thread.NORM_PRIORITY);

System.out.println("Group's maximum priority = " +
groupNORM.getMaxPriority());
System.out.println("Thread's priority = " +
priorityMAX.getPriority());
}
}

When the ThreadGroup groupNORM is created, it inherits its maximum priority attribute from its parent thread group. In this case, the parent group priority is the maximum (MAX_PRIORITY) allowed by the Java runtime system. Next the program sets the priority of the priorityMAX thread to the maximum allowed by the Java runtime system. Then the program lowers the group's maximum to the normal priority (NORM_PRIORITY). The setMaxPriority method does not affect the priority of the priorityMAX thread, so that at this point, the priorityMAX thread has a priority of 10, which is greater than the maximum priority of its group, groupNORM. This is the output from the program:
Group's maximum priority = 5
Thread's priority = 10

As you can see a thread can have a higher priority than the maximum allowed by its group as long as the thread's priority is set before the group's maximum priority is lowered. A thread group's maximum priority is used to limit a thread's priority when the thread is first created within a group or when you use setPriority to change the thread's priority. Note that setMaxPriority does change the maximum priority of all of its descendant-threadgroups.

Similarly, a group's daemon status applies only to the group. Changing a group's daemon status does not affect the daemon status of any of the threads in the group. Furthermore, a group's daemon status does not in any way imply the daemon status of its threads--you can put any thread within a daemon thread group. The daemon status of a thread group simply indicates that the group will be destroyed when all of its threads have been terminated.

Related Posts:-

ThreadGroup Class - Collection Management Methods


The ThreadGroup provides a set of methods that manage the threads and subgroups within the group and allow other objects to query the ThreadGroup for information about its contents. For example, you can call ThreadGroup's activeCount method to find out the number of active threads currently in the group. The activeCount method is often used with the enumerate method to get an array filled with references to all the active threads in a ThreadGroup. For example, the listCurrentThreads method in the following example fills an array with all of the active threads in the current thread group and prints their names:

class EnumerateTest {
void listCurrentThreads() {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int numThreads;
Thread[] listOfThreads;


numThreads = currentGroup.activeCount();
listOfThreads = new Thread[numThreads];
currentGroup.enumerate(listOfThreads);
for (int i = 0; i < numThreads; i++) {
System.out.println("Thread #" + i + " = " + listOfThreads[i].getName());
}
}
}
Other collection management methods provided by the ThreadGroup class include activeGroupCount and list.

Related Posts:-

Java - ThreadGroup Class

The ThreadGroup class manages groups of threads for Java applications. A ThreadGroup can contain any number of threads. The threads in a group are generally related in some way, such as who created them, what function they perform, or when they should be started and stopped.

ThreadGroups can contain not only threads but also other ThreadGroups. The top-most thread group in a Java application is the thread group named main. You can create threads and thread groups in the main group. You can also create threads and thread groups in subgroups of main. The result is a root-like hierarchy of threads and thread groups:


The ThreadGroup class has methods that can be categorized as follows:

Java - Thread Group

Every Java thread is a member of a thread group. Thread groups provide a mechanism for collecting multiple threads into a single object and manipulating those threads all at once, rather than individually. For example, you can start or suspend all the threads within a group with a single method call. Java thread groups are implemented by the ThreadGroup class in the java.lang package.

The runtime system puts a thread into a thread group during thread construction. When you create a thread, you can either allow the runtime system to put the new thread in some reasonable default group or you can explicitly set the new thread's group. The thread is a permanent member of whatever thread group it joins upon its creation--you cannot move a thread to a new group after the thread has been created.

The Default Thread Group

If you create a new Thread without specifying its group in the constructor, the runtime system automatically places the new thread in the same group as the thread that created it (known as the current thread group and the current thread, respectively). So, if you leave the thread group unspecified when you create your thread, what group contains your thread?
When a Java application first starts up, the Java runtime system creates a ThreadGroup named main. Unless specified otherwise, all new threads that you create become members of the main thread group.

Many Java programmers ignore thread groups altogether and allow the runtime system to handle all of the details regarding thread groups. However, if your program creates a lot of threads that should be manipulated as a group, or if you are implementing a custom security manager, you will likely want more control over thread groups.

Creating a Thread Explicitly in a Group

As mentioned previously, a thread is a permanent member of whatever thread group it joins when its created--you cannot move a thread to a new group after the thread has been created. Thus, if you wish to put your new thread in a thread group other than the default, you must specify the thread group explicitly when you create the thread. The Thread class has three constructors that let you set a new thread's group:

public Thread(ThreadGroup group, Runnable target)
public Thread(ThreadGroup group, String name)
public Thread(ThreadGroup group, Runnable target, String name)

Each of these constructors creates a new thread, initializes it based on the Runnable and String parameters, and makes the new thread a member of the specified group. For example, the following code sample creates a thread group (myThreadGroup) and then creates a thread (myThread) in that group.

ThreadGroup myThreadGroup = new ThreadGroup("My Group of Threads");
Thread myThread = new Thread(myThreadGroup, "a thread for my group");

The ThreadGroup passed into a Thread constructor does not necessarily have to be a group that you create--it can be a group created by the Java runtime system, or a group created by the application in which your applet is running.

Getting a Thread's Group
To find out what group a thread is in, you can call its getThreadGroup method:
theGroup = myThread.getThreadGroup();

Thread - Deadlock

There are situations when programs become deadlocked when each thread is waiting on a resource that cannot become available. The simplest form of deadlock is when two threads are each waiting on a resource that is locked by the other thread. Since each thread is waiting for the other thread to relinquish a lock, they both remain waiting forever in the Blocked-for-lock-acquisition state. The threads are said to be deadlocked.

Thread t1 at tries to synchronize first on string o1 and then on string o2. The thread t2 does the opposite. It synchronizes first on string o2 then on string o1. Hence a deadlock can occur as explained above.

Below is a program that illustrates deadlocks in multithreading applications

public class DeadLockExample {

String o1 = "Lock ";
String o2 = "Step ";
Thread t1 = (new Thread("Printer1") {

public void run() {
while (true) {
synchronized (o1) {
synchronized (o2) {
System.out.println(o1 + o2);
}
}
}
}
});
Thread t2 = (new Thread("Printer2") {

public void run() {
while (true) {
synchronized (o2) {
synchronized (o1) {
System.out.println(o2 + o1);
}
}
}
}
});
public static void main(String[] args) {
DeadLockExample dLock = new DeadLockExample();
dLock.t1.start();
dLock.t2.start();
}
}

Java - Thread Joining

A thread invokes the join() method on another thread in order to wait for the other thread to complete its execution.
Consider a thread t1 invokes the method join() on a thread t2. The join() call has no effect if thread t2 has already completed. If thread t2 is still alive, then thread t1 transits to the Blocked-for-join-completion state.

Below is a program showing how threads invoke the overloaded thread join method.

public class ThreadJoinDemo {

public static void main(String[] args) {
Thread t1 = new Thread("T1");
Thread t2 = new Thread("T2");
try {
System.out.println("Wait for the child threads to finish.");
t1.join();
if (!t1.isAlive())
System.out.println("Thread T1 is not alive.");
t2.join();
if (!t2.isAlive())
System.out.println("Thread T2 is not alive.");
} catch (InterruptedException e) {
System.out.println("Main Thread interrupted.");
}
System.out.println("Exit from Main Thread.");
}
}

Output
Wait for the child threads to finish.
Thread T1 is not alive.
Thread T2 is not alive.
Exit from Main Thread.

Java - The notify() and wait() Methods

The get() and put() methods in the CubbyHole object both make use of the notify() and wait() methods to coordinate getting and putting values into the CubbyHole. Both notify() and wait() are members of the java.lang.Object class.
The notify() and wait() methods can only be called from a synchronized method.

The notify() method

The get() method calls notify() as the last thing it does (besides return). The notify() method chooses one thread that is waiting on the monitor held by the current thread and wakes it up. Typically, the waiting thread will grab the monitor and proceed.

In the case of the Producer/Consumer example, the Consumer thread calls the get() method, so the Consumer thread holds the monitor for the CubbyHole during the execution of get(). At the end of the get() method, the call to notify() wakes up the Producer thread which is waiting on the CubbyHole's monitor. Now, the Producer thread can get the CubbyHole monitor and proceed.

public synchronized int get(){
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notify(); // notifies Producer
return seq;
}

If multiple threads were waiting for the CubbyHole monitor, the Java runtime system chooses one of the waiting threads, and makes no commitments or guarantees about which thread will be chosen.

The put() method works in a similar fashion waking up the Consumer thread that is waiting for the Producer to release the monitor.

The Object class has another method--notifyAll()--that wakes up all the threads waiting on the same monitor. In this situation, the awakened threads compete for the monitor. One thread gets the monitor and the others go back to waiting.
The wait() method

The wait() method causes the current thread to wait (possibly forever) until another thread notifies it of a condition change. You use wait() in conjunction with notify() to coordinate the activities of multiple threads using the same resources.

The get() contains a while statement that loops until available becomes true. If available is false, then the Consumer knows that the Producer has not yet produced a new number and the Consumer should wait until it has.

The while loop contains the call to wait(). The wait() method waits indefinitely for a notification from the Producer thread. When the put() method calls notify(), the Consumer wakes up from the wait state and continues within the while loop. Presumably, the Producer has generated a new number and the get() method drops out of the while loop and proceeds. If the Prodcuer had not generated a number, get() would go back to the beginning of the loop and continue to wait until the Producer had generated a new number and called notify().

public synchronized int get() {
while (available == false) {
try {
wait(); // waits for notify() call from Producer
} catch (InterruptedException e) {
}
}
available = false;
notify();
return seq;
}

The put() method works in a similar fashion waiting for the Consumer thread to consume the current value before allowing the Producer to produce a new one.

Besides the version used in the Producer/Consumer example which waits indefinitely for notification, the Object class contains two other versions of the wait() method:

wait(long timeout)

waits for notification or until the timeout period has elapsed--timeout is measured in milliseconds.

wait(long timeout, int nanos)

waits for notification or until the timeout period plus the additional nanoseconds has elapsed.

Java - Thread Scheduler


Schedulers in JVM implementations usually employ one of the two following strategies:

Preemptive scheduling

If a thread with a higher priority than all other Runnable threads becomes Runnable, the scheduler will preempt the running thread (is moved to the runnable state) and choose the new higher priority thread for execution.

Time-Slicing or Round-Robin scheduling

A running thread is allowed to execute for a fixed length of time (a time slot it’s assigned to), after which it moves to the Ready-to-run state (runnable) to await its turn to run again.

A thread scheduler is implementation and platform-dependent; therefore, how threads will be scheduled is unpredictable across different platforms.

Java - Thread Synchronized Blocks

The synchronized block allows execution of arbitrary code to be synchronized on the lock of an arbitrary object.

A compile-time error occurs if the expression produces a value of any primitive type. If execution of the block completes normally, then the lock is released. If execution of the block completes abruptly, then the lock is released.

A thread can hold more than one lock at a time. Synchronized statements can be nested. Synchronized statements with identical expressions can be nested. The expression must evaluate to a non-null reference value, otherwise, a NullPointerException is thrown.

The code block is usually related to the object on which the synchronization is being done. This is the case with synchronized methods, where the execution of the method is synchronized on the lock of the current object:

public Object method() {
synchronized (this) { // Synchronized block on current object
// method block
}
}

Once a thread has entered the code block after acquiring the lock on the specified object, no other thread will be able to execute the code block, or any other code requiring the same object lock, until the lock is relinquished. This happens when the execution of the code block completes normally or an uncaught exception is thrown.

Object specification in the synchronized statement is mandatory. A class can choose to synchronize the execution of a part of a method, by using the this reference and putting the relevant part of the method in the synchronized block. The braces of the block cannot be left out, even if the code block has just one statement.

class SmartClient {
BankAccount account;
// …
public void updateTransaction() {
synchronized (account) { // (1) synchronized block
account.update(); // (2)
}
}
}

In the previous example, the code at (2) in the synchronized block at (1) is synchronized on the BankAccount object. If several threads were to concurrently execute the method updateTransaction() on an object of SmartClient, the statement at (2) would be executed by one thread at a time, only after synchronizing on the BankAccount object associated with this particular instance of SmartClient.

In summary, a thread can hold a lock on an object
  • by executing a synchronized instance method of the object
  • by executing the body of a synchronized block that synchronizes on the object
  • by executing a synchronized static method of a class
Related Post :-

Java - Thread Synchronized Method

The Tutorial want to explain you a code that help you in understanding Java Method Synchronized. We have a class Synchronized Method. In order to make a method Synchronized, we add synchronized keyword to the method. The synchronized int get Count ( ) method return you the count of thread executed in a code.

The static void print(String ms) includes a Thread.currentThread ( ).get Name( ) return you the name of the current thread. The print ln print the thread Name.

Inside the main method, The run ( ) method used to create a thread, that causes the thread to be started and each thread executed separately in the application. The print ln method print the count of thread by calling from get Count ( ).

Thread threadA =new Thread(Runnable,"Thread A"): The new is used to describe that thread is created but not yet started.

Thread.start ( ): This causes the thread to start and ready for execution.

Thread.sleep ( ):This causes the currently executing thread to sleep (cease execution) as per specified number of millisecond.

On execution the code show you the count of thread and execute each thread after 500 millisecond. In case the exception exists in try block,the catch block caught and handle the exception


Here is the code:

public class SynchronizedMethod extends Object {
private static int count = 1;
public static synchronized int getCount() {
int i = count;
count++;
return i;
}
private static void print(String msg) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + ": " + msg);
}
public static void main(String[] args) {
try {
Runnable runnable = new Runnable() {
public void run() {
System.out.println("count=" + getCount());
}
};
Thread threadA = new Thread(runnable, "ThreadA");
threadA.start();
Thread.sleep(500);
Thread threadB = new Thread(runnable, "ThreadB");
threadB.start();
Thread.sleep(500);
Thread threadC = new Thread(runnable, "ThreadC");
threadC.start();
Thread.sleep(500);
Thread threadD = new Thread(runnable,
"ThreadD");
threadD.start();
} catch(Exception x ) {}
}
}
}

Output will be displayed as:












Related Post:-

Java - Thread Synchronization

With respect to multithreading, Synchronization is a process of controlling the access of shared resources by the multiple threads in such a manner that only one thread can access a particular resource at a time.

In non synchronized multithreaded application, it is possible for one thread to modify a shared object while another thread is in the process of using or updating the object’s value. Synchronization prevents such type of data corruption which may otherwise lead to dirty reads and significant errors.

Generally critical sections of the code are usually marked with synchronized keyword. Locks are used to synchronize access to a shared resource. A lock can be associated with a shared resource.

Threads gain access to a shared resource by first acquiring the lock associated with the object/block of code.

At any given time, at most only one thread can hold the lock and thereby have access to the shared resource.

A lock thus implements mutual exclusion.
The object lock mechanism enforces the following rules of synchronization:

A thread must acquire the object lock associated with a shared resource, before it can enter the shared resource. The runtime system ensures that no other thread can enter a shared resource if another thread already holds the object lock associated with the shared resource. If a thread cannot immediately acquire the object lock, it is blocked, that is, it must wait for the lock to become available.
  • When a thread exits a shared resource, the runtime system ensures that the object lock is also relinquished.If another thread is waiting for this object lock, it can proceed to acquire the lock in order to gain accessto the shared resource.
Classes also have a class-specific lock that is analogous to the object lock. Such a lock is actually a lock on the java.lang.Class object associated with the class. Given a class A, the reference A.class denotes this unique Class object. The class lock can be used in much the same way as an object lock to implement mutual exclusion.

There can be 2 ways through which synchronized can be implemented in Java:
  • synchronized methods
  • synchronized blocks

Synchronized statements are same as synchronized methods. A synchronized statement can only be executed after a thread has acquired the lock on the object/class referenced in the synchronized statement.

Related Post:-

Java - Thread Priorities


Every thread has a priority assigned to it. Thread priority in Java has the effect of controlling the flow of program. Here I will describe Java thread priorities and also share same code for defining priorities to Java threads.

Since with the use of multi threading, there is no defined order in which the threads will execute. But Java provides few mechanisms by using which one can control the execution of multiple threads to some extent and assign thread priorities to them.

In Java, threads can have three level of priorities viz:
1) Min Priority 2) Normal Priority 3) High Priority

One can assign priority to a thread in Java by using the setPriority() method. One important point to note about thread priorities in Java is that it is not guaranteed that a thread with higher priority will always get preference for execution than a thread with lower priority. It all depends upon the thread scheduler to decide which thread to execute currently.

The use of assigning priority to a Java thread is that it is just a hint to thread scheduler to decide which thread is more important for execution and hence give more preference to that thread.
Thread Priorities Example code:

package com.example;

public class MyClass extends Thread{
public void run() {
System.out.println(Thread.currentThread().getName());
}

public static void main(String[] args) throws Exception {
MyClass t1 = new MyClass();
MyClass t2 = new MyClass();

t1.setName("Thread 1");
t2.setName("Thread 2");

t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);

t1.start();
t2.start();
}
}

Output:
Thread 2 or Thread 1
Thread 1 Thread 2

Conclusion and Analysis

Out of every 10 times I execute the above code, Thread 2 gets executed before Thread 1 8 times and the reverse happens only 2 times.

Moreover, if I don’t assign thread priorities in the above code then out of every 10 times, Thread 1 gets executed before Thread 2.

This clearly indicates that assigning a higher priority to a thread does make it more likely that the higher priority thread will get executed before low priority thread. Again, the above statement may not always be true.

Java - States of Thread

The following diagram illustrates the various states that a Java thread can be in at any point during its life. It also illustrates which method calls cause a transition to another state. This diagram is not a complete finite state diagram, but rather an overview of the more interesting and common aspect of a thread's life. The remainder of this page discusses a Thread's life cycle in terms of its state.


New Thread

The following statement creates a new thread but does not start it, thereby leaving the thread in the "New Thread" state.

Thread myThread = new MyThreadClass();

When a thread is in the "New Thread" state, it is merely an empty Thread object. No system resources have been allocated for it yet. Thus when a thread is in this state, you can only start the thread or stop it. Calling any method besides start() or stop() when a thread is in this state makes no sense and causes an IllegalThreadStateException.

Runnable

Now consider these two lines of code:

Thread myThread = new MyThreadClass();
myThread.start();

The start() method creates the system resources necessary to run the thread, schedules the thread to run, and calls the thread's run() method. At this point the thread is in the "Runnable" state. This state is called "Runnable" rather than "Running" because the thread might not actually be running when it is in this state. Many computers have a single processor, making it impossible to run all "Runnable" threads at the same time. So, the Java runtime system must implement a scheduling scheme that shares the processor between all "Runnable" threads. (See Thread Priority for more information about scheduling.) However, for most purposes you can think of the "Runnable" state as simply "Running". When a thread is running--it's "Runnable" and is the current thread--the instructions in its run() method are executing sequentially.

Not Runnable

A thread enters the "Not Runnable" state when one of these four events occurs:
  • Someone invokes its sleep() method.
  • Someone invokes its suspend() method.
  • The thread uses its wait() method to wait on a condition variable.
  • The thread is blocking on I/O.
For example, the bold line in the following code snippet puts the current thread to sleep for 10 seconds (10,000 milliseconds):

try {
Thread.sleep(10000);
} catch (InterruptedException e){
}

During the 10 seconds that myThread is asleep, even if the processor becomes available myThread does not run. After the 10 seconds are up, myThread becomes "Runnable" again and, if the processor becomes available, runs.

For each of the entrances into the "Not Runnable" state shown in the figure, there is a specific and distinct escape route that returns the thread to the "Runnable" state. An escape route only works for its corresponding entrance. For example, if a thread has been put to sleep, then the specified number of milliseconds must elapse before the thread becomes "Runnable" again. Calling resume() on a sleeping thread has no effect.

The following indicates the escape route for every entrance into the "Not Runnable" state.
  • If a thread has been put to sleep, then the specified number of milliseconds must elapse.
  • If a thread has been suspended, then someone must call its resume() method.
  • If a thread is waiting on a condition variable, whatever object owns the variable must relinquish it by calling either notify() or notifyAll().
  • If a thread is blocked on I/O, then the I/O must complete.
Dead
A thread can die in two ways: either from natural causes, or by being killed (stopped). A thread dies naturally when its run() method exits normally. For example, the while loop in this method is a finite loop--it will iterate 100 times and then exit.

public void run() {
int i = 0;
while (i < 100) {
i++;
System.out.println("i = " + i);
}
}

A thread with this run() method will die naturally after the loop and the run() method completes.
You can also kill a thread at any time by calling its stop() method. The following code snippet creates and starts myThread then puts the current thread to sleep for 10 seconds. When the current thread wakes up, the bold line in the code segment kills myThread.

Thread myThread = new MyThreadClass();
myThread.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e){
}
myThread.stop();

The stop() method throws a ThreadDeath object at the thread to kill it. Thus when a thread is killed in this manner it dies asynchronously. The thread will die when it actually receives the ThreadDeath exception.

The stop() method causes a sudden termination of a Thread's run() method. If the run() method performs critical or sensitive calculations, stop() may leave the program in an inconsistent or awkward state. Normally, you should not call Thread's stop() method but arrange for a gentler termination such as setting a flag to indicate to the run() method that it should exit.

IllegalThreadStateException

The runtime system throws an IllegalThreadStateException when you call a method on a thread and that thread's state does not allow for that method call. For example, IllegalThreadStateException is thrown when you invoke suspend() on a thread that is not "Runnable".

As shown in the various examples of threads so far in this lesson, when you call a thread method that can throw an exception, you must either catch and handle the exception, or specify that the calling method throws the uncaught exception.

The isAlive() Method

A final word about thread state: the programming interface for the Thread class includes a method called is Alive(). The isAlive() method returns true if the thread has been started and not stopped. Thus, if the isAlive() method returns false you know that the thread is either a "New Thread" or "Dead". If the isAlive() method returns true, you know that the thread is either "Runnable" or "Not Runnable". You cannot differentiate between a "New Thread" and a "Dead" thread; nor can you differentiate between a "Runnable" thread and a "Not Runnable" thread.

Thread methods in Java

On the previous post, we looked at how to create a thread in Java, via the Runnable and Thread objects. We mentioned that the Thread class provides control over threads. So on this page, we take a high-level look at the most important methods on this class.

Thread.sleep()

We actually saw a sneak preview of Thread.sleep() in our Java threading introduction. This static method asks the system to put the current thread to sleep for (approximately) the specified amount of time, effectively allowing us to implement a "pause". A thread can be interrupted from its sleep.
For more details, see: Thread.sleep() (separate page).

interrupt()

As mentioned, you can call a Thread object's interrupt() method to interrupt the corresponding thread if it is sleeping or waiting. The corresponding thread will "wake up" with an IOException at some point in the future. See thread interruption for more details.

setPriority() / getPriority()

Sets and queries some platform-specific priority assignment of the given thread. When calculating a priority value, it's good practice to always do so in relation to the constants Thread.MIN_PRIORITY, Thread.NORM_PRIORITY and Thread.MAX_PRIORITY. In practice, values go from 1 to 10, and map on to some machine-specific range of values: nice values in the case of Linux, and local thread priorities in the case of Windows. These are generally the range of values of "normal" user threads, and the OS will actually still run other threads beyond these values (so, for example, you can't preempt the mouse pointer thread by setting a thread to MAX_PRIORITY!).
Three main issues with thread priorities are that:
  • they don't always do what you might intuitively think they do;
  • their behaviour depends on the platform and Java version: e.g. in Linux, priorities don't work at all in Hotspot before Java 6, and the mapping of Java to OS priorities changed under Windows between Java 5 and Java 6;
  • in trying to use them for some purpose, you may actually interfere with more sensible scheduling decisions that the OS would have made anyway to achieve your purpose.
For more information, see the section on thread scheduling and the discussion on thread priorities, where the behaviour on different platforms is compared.

join()

The join() method is called on the Thread object representing enother thread. It tells the current thread to wait for the other thread to complete. To wait for multiple threads at a time, you can use a CountDownLatch.

Thread.yield()

This method effectively tells the system that the current thread is "willing to relinquish the CPU". What it actually does is quite system-dependent. For more details, see: Thread.yield() (separate page).

setName() / getName()

Threads have a name attached to them. By default, Java will attach a fairly dull name such as Thread-12. But for debugging purposes you might want to attach a more meaningful name such as Animation Thread, WorkerThread-10 etc. (Some of the variants of the Thread constructor actually allow you to pass in a name from the start, but you can always change it later.)

Other thread functions

There are occasionally other things that you may wish to do with a thread that don't correspond to a single method. In particular, there is no safe method to stop a thread, and instead you should simply let the corresponding run() method exit.

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More