What are the advantages or usage of threads?

Ans)
Threads support concurrent operations. For example,
-- Multiple requests by a client on a server can be handled as an individual client thread.
-- Long computations or high-latency disk and network operations can be handled in the background without disturbing foreground computations or screen updates.

Threads often result in simpler programs.
-- In sequential programming, updating multiple displays normally requires a big while-loop that performs small parts of each display update. Unfortunately, this loop basically simulates an operating system scheduler. In Java, each view can be assigned a thread to provide continuous updates.
-- Programs that need to respond to user-initiated events can set up service routines to handle the events without having to insert code in the main routine to look for these events.

Threads provide a high degree of control.
-- Imagine launching a complex computation that occasionally takes longer than is satisfactory. A "watchdog" thread can be activated that will "kill" the computation if it becomes costly, perhaps in favor of an alternate, approximate solution. Note that sequential programs must muddy the computation with termination code, whereas, a Java program can use thread control to non-intrusively supervise any operation.

Threaded applications exploit parallelism.
-- A computer with multiple CPUs can literally execute multiple threads on different functional units without having to simulating multi-tasking ("time sharing").
-- On some computers, one CPU handles the display while another handles computations or database accesses, thus, providing extremely fast user interface response times.

Difference between Multithreading and Multiprocessing

Multi-threading refers to an application with multiple threads running within a process, while multi-processing refers to an application organised across multiple OS-level processes.
A thread is a stream of instructions within a process. Each thread has its own instruction pointer, set of registers and stack memory. The virtual address space is process specific, or common to all threads within a process. So, data on the heap can be readily accessed by all threads, for good or ill.
Multi-threading is a more "light weight" form of concurrency: there is less context per thread than per process. As a result thread lifetime, context switching and synchronisation costs are lower. The shared address space (noted above) means data sharing requires no extra work.
Multi-processing has the opposite benefits. Since processes are insulated from each other by the OS, an error in one process cannot bring down another process. Contrast this with multi-threading, in which an error in one thread can bring down all the threads in the process. Further, individual processes may run as different users and have different permissions.

Difference between multitasking multiprogramming and multithreading?

Multiprogramming is a rudimentary form of parallel processing in which several programs are run at the same time on a uniprocessor.Since there is only one processor, there can be no true simultaneous execution of different programs. Instead, the operating system executes part of one program, then part of another, and so on. To the user it appears that all programs are executing at the same time.

Multitasking, in an operating system, is allowing a user to perform more than one computer task (such as the operation of an application program) at a time. The operating system is able to keep track of where you are in these tasks and go from one to the other without losing information

Multithreading is the ability of a program or an operating system process to manage its use by more than one user at a time and to even manage multiple requests by the same user without having to have multiple copies of the program running in the computer

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:-

Some Unique Guinness World Records


1,253 Smurfs gathered in the high street in the town of Castleblayney in County Monaghan, Ireland on July 18, 2008. (Guinness World Records)

35,310 Lego Star Wars Clone Troopers in the UK.


The longest skis are 534 m long and were worn by 1,043 skiers in an event organized by Danske Bank on Drottninggatan in Örebro, Sweden, on 13 September 2008.

World's biggest pickup truck - 2002




Surrey resident Sarwan Singh achieved a feat, which every Sikh is going to be proud of. He set a new Guinness Book of World Record by having the longest beard.


The largest pocket knife was designed by Telmo Cadavez and hand made by Virgilio, Raul and Manuel Pires of Portugal. The knife is 3.9m long when open and weighs 122kg.





The largest commercially available hamburger is 74.75 kg (164.8 lbs) and is available for US$399 (£271.55) on the menu at Mallie's Sports Grill & Bar in Southgate, Michigan, USA, as of 29 August 2008.


In Germany, Anita Schwarz set a new record for carrying the most steins of lager over 40m. She staggered across the finishing line holding 19 glasses.


Coke & Mentos Guiness world record With 1,911 explosions in Riga, Latvia.






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.

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More