Witscale Test Center

Chapter summary


Chapter summary

This chapter covers entire seventh SCJP objective with all four sections 7.1, 7.2, 7.3 and 7.4. Threads are thought to be one of the most difficult topics in SCJP, The exam also has lot of questions on threads. In this chapter, we learned what threads are and how to create them. We quickly overviewed the life cycle of thread and different states it can be in. We then learned the various conditions and method calls that can cause an executing thread to stop its execution and go to some other state. Then, we took a close look at how you can protect data (and critical code)  from simultaneous modifications by multiple threads. In that we learned about the locking mechanism and how to ensure the proper access with synchronized code. Finally, we learned how the threads interact with each other and also how to implement the wait-and-notify thread interaction with an example. Here is a brief summary of concepts we learned.

 

       Thread basics

 

Defining, Instantiating threads

1.       Subclass the java.lang.Thread and override its run() method.

2.       Implement the java.lang.Runnable Interface.

1.       Create an instance of Thread class or create an instance of a subclass of Thread. The instance of Thread class is not very useful, as its run() method does not do anything.

2.       Thread objects can also be created by calling the Thread constructor that takes a Runnable argument. The Runnable object is said to be the target of the thread because when the thread is executed it executes the Runnable object’s run method.

 

Starting a thread

 

Thread States and state transitions

1.         Ready-to-run

2.         Running

3.         Not-ready-to-run(waiting/blocked/sleeping)

4.         Dead

A thread voluntarily moves from running to ready-to-run state by a call to Thread.yield() method.

 

Thread Scheduling

 

Method calls that can prevents the thread from executing (takes a  thread out-of the running state)     

§          The setPriority() is an instance method that is used to give threads a priority between 1 (lowest priority) and 10 (highest).

§          Priorities are not guaranteed to take effect and thread scheduler may not implement all 10 levels.

§          When priority is not explicitly set, a thread’s priority will be the same priority as the thread that created this thread. The thread created by JVM such as main thread created by invoking main method has a priority of 5 at startup.

 

§          It is a static method. It puts the currently executing thread to sleep.

§          Since it is static method, no matter whether you call it on a thread instance or Thread class, it always works the same.

§          One thread cannot put another thread to sleep.

§          Sleeping is used to delay the execution of its executing thread for a stipulated period.

§          A sleeping thread is guaranteed to sleep for at least the time specified in the argument to the sleep method (unless it is interrupted).

§          It is not guaranteed when the thread will actually start to running after it wakes up.

§          A thread does not release the locks it is holding when it is sleeping.

 

§          This is a static method that causes a running thread to voluntarily give up its turn of execution

§          If there are ready-to-run threads of the same priority in the thread pool, they may get a chance to execute. But there is no guarantee that this will happen as whether thread scheduler respect priority itself is implementation dependent.

§          There is no guarantee that when the thread that just yielded is not selected to run. A thread might yield and then immediately re-enter the running state because thread scheduler picked it again.

§          The closest thing that can be guaranteed about yield is that it gives fair chance of execution to its fellow (same or lower) priority thread. It does not change anything for a high-priority threads though. When a high priority thread enters the thread pool, a (priority-based) thread scheduler will anyway force out the currently running low-priority thread and give the high-priority thread a chance to execute.

§          This is an instance method of Thread class.

§          It is used to join one thread’s execution with another.

§          When one thread calls the join() method of another thread, the currently running thread will wait until the thread it joins with has completed (and dead).

§          The invocation of  doItFirst.join() method in a someJob thread is as someJob saying, “Hey doItFirst, I would like to join on at the end of you. Let me know when you are done, so I can be the ready-to-run (roll) again.”

 

Protecting data and critical code using synchronization and locks

§          Synchronized methods prevent more than one thread from accessing an object’s critical method code.

§          You can use the synchronized keyword as a method modifier, or at the start code block to synchronize the code.

§          When you synchronize a block of code, you must specify an object (whose state you are protecting from concurrent access) as an argument.

§          While only one thread can access the synchronized code on an object, multiple threads can still access the same object’s unsynchronized code.

§          Static methods can be synchronized, using the lock on an instance of java.lang.Class representing that class in JVM.

 

§          Every object in Java has a built-in lock.

§          It comes into play only when the object has synchronized code. This lock symbolizes the authority to execute the synchronized code.

§          Whenever a thread encounters a synchronized code during execution, it must acquire the relevant object’s lock. 

§          Since there is only one lock per object, only one thread can own it at a time. Therefore, only one thread can execute the synchronized code at a time.

 

§          Thread keeps the acquired lock even when it is not running.

§          A thread can acquire more than one lock.

§          A thread need not re-acquire the object’s lock while calling a synchronized method from another synchronized method of the same object.

§          A thread might have to wait as well as contend for acquiring a lock on an object.

 

§          Deadlock is undesirable situation in which the thread execution is ceased because the threads are waiting forever each seeking the lock held by another.

§          Deadlocked threads can run forever without any resolution.

§          Java does not provide any mechanisms for detection or control of deadlock situations, so the programmer is responsible for avoiding them.

§          One simple way to avoid deadlock is to acquire the locks in a predetermined fashion so that a thread will never block for a lock that it will get only when it releases one of the locks it is holding.

 

q       Thread interaction with wait-and-notify

§          Java threads communicate about the status of shared objects using the wait-and-notify mechanism.

§          The methods wait(),notify() and notifyAll() are instance methods of Object.

§          A thread that invokes the wait() and notify() methods on an object, must own that object’s lock.

 

       The wait() method

 

       notify() and notifyAll()

 

       Summary of all methods useful in threading

 

Types

Methods

java.lang.Object

Instance methods

wait()

notify()

notifyAll()

java.lang.Thread

Instance methods

start()

run()

join()

setPriority()

isAlive()

Static methods

sleep()

yield()

currentThread()

java.lang.Runnable

run()