Monday, February 28, 2011

Chapter 3: A Sample Servet

We saw what the purpose of a Servlet Container and a Web server is, in the previous chapter. In this chapter, we are going to look at how a Servlet code would look like.

So, lets get started!!!

Servlet Skeleton

If I ask you, what are the components of a Java class, you’ll happily tell me that, there are first package statements and then imports and then the class declaration. Within the class brackets, we have constructors, instance variables, methods etc. That was easy, wasn’t it?

The same way, every Servlet has a certain set of components that are mandatory for its well-being. (I just got carried away a bit) Or I must say, for its proper functioning.

A Servlets skeleton would look like below:

/*
* servlet name
*
* servlet description
* All other stuff that is part of a Standard Class comment section
*/

//package declarations

//import statements

public class ServletName extends HttpServlet {

// Instance Variables

/**
* Code to Initialize the Servlet
*/
public void init() throws ServletException
{
// Servlet Initialization Code goes here
}

/**
* The Service Method
* Gets invoked for every request submitted to the Servlet
* This method is optional. We mostly use doGet, doPost Methods
*/
protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
// Code for the Service Method goes here
}


/**
* Process a GET request
*
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// Code for the doGet() method goes here
}

/**
* Process a POST request
*
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// Code for the doPost() method goes here
}

/**
* Process a PUT request
*
*/
protected void doPut(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
//Code for the doPut() method goes here
}

/**
* You can have any number of methods for your processing
* here. There is no limit as to the number of methods or
* any restrictions on what you can name them.
* Since this is all java code, you need to keep them
* syntactically correct as per Java Coding Standards.
*/

/**
* Clean-Up
*/
public void destroy()
{
// clean up activities before the Servlet is put to death
}
}


The above is what a Servlets skeleton would look like. Now let us take a look at some sample code as to how a properly coded Servlet would look like:


import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.PrintWriter;
import java.io.IOException;


public class OurFirstServlet extends HttpServlet
{

public void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("< html >");
out.println("< head >< title >Servlet Example " +
" ");
out.println("< body >");
out.println("Not Much code, but this is enough for a Servlet.");
out.println("");
out.println("");
}
}

The above is a simple Servlet. It would display an almost blank HTML page that contains the message we put in “Not Much code, but this is enough for a Servlet.”

Note: A Servlet is not a simple java class, that you can run using a main() method. You have deploy this Servlet on a web server in order to view the output. Lets not get too ahead of ourselves here. We’ll be looking at all that later in detail. For now, this is how a Servlet would look like and that wraps up our current chapter.

Previous Chapter: Web Servers & Servlet Containers

Next Chapter: A sample JSP

Chapter 2: Web Servers and Servlet Containers

In the previous chapter we looked at the history of the Web (Internet) and how JSPs and Servlets came into being. As you might have already guessed by now, any J2EE application needs a server on which it runs. It is called a Web Server. Also, the Servlet needs something in which it would run (Think of the JVM in which all java applications run) and that is called the Servlet container.

In this chapter, we are going to take a look at these two entities.

So, lets get started!!!

Web Servers and Servlet Containers

A servlet is nothing but Java code that runs in a container. It generates HTML & other contents that get displayed in the web page that we see. It is purely coded in Java, so the benefits and restrictions of all regular Java classes apply here too. Servlets are compiled to form a platform neutral bytecode (All java code is platform neutral, isnt it? Serlvet is no different). Upon request, this bytecode file is loaded into a container. Some containers (servlet engines) are integrated with the Web server, while others are plug-ins or extensions to Web servers that run inside the JVM. Servlets look the same as static Web pages to the client, but they really are complete programs capable of complex operations.

The servlet container is an extension of a Web server in the same way CGI, ASP, and PHP are. A servlet functions just like them, but the language in which it is written is Java. That's the main difference. The servlet doesn't talk to the client directly. The Web server functions as the intermediary that does it for the servlet. In a chain of processes, the client sends a request to the Web server, which hands it to the container, which hands it to the servlet. The Servlet processes the request and generates a response. The response starts from the servlet and goes to the container and then to the Web server and back to the client. Of course there are several other steps that happen too but this is just the introduction so this much would suffice I believe.

The servlet architecture makes the container manage servlets through their lifecycle. The container invokes a servlet upon receiving an HTTP request, providing that servlet with request information and the container configurations. The servlet uses this to do its job which is processing the data it received as part of the request. When finished, it hands back HTML and objects that hold information about the response. The container then forms an HTTP response and returns it to the client which inturn displays the stuff sent by the Servlet on screen in the web browser.

Below is a simple illustration of the flow of control that starts and ends at the Web Browser. Control starts at the browser, goes to the server and then to the container which in turn invokes the Servlet. Our Servlet happily does the processing (which might involve hitting a database) and returns the data to the container which in turn passes it on to the web server which finally displays the contents on the web browser.


The Servlet container is often written in Java, since it eventually runs inside a JVM. However, some vendors implement their containers in different languages (they aren’t essentially bound to Java). The point here is the fact that, all we need is a servlet container that can read and execute our servlets. The language in which it is implemented is not necessarily important for us.

Previous Chapter: Chapter 1 - Servlet & JSP History

Next Chapter: A Sample Servlet

Chapter 1: Servlet & JSP History

Here we are, studying for the SCWCD exam. I would like to congratulate you again for this decision of yours because of which you are going to get yourself SCWCD certified. It's a big step and am gonna be with you step by step to help you get this certification.

Well, it wouldn't be much fun preparing for a certification on JSPs and Servlets without knowing their history. Would it?

This chapter is going to be a history lesson taking you to the humble beginnings of these two wonderful technologies that have made our lives so much more easier & powerful.

How it all Began – Internet

Early in the 1950’s computer scientists in USA were working their backsides off in order to compete with Soviet Unions (The late USSR) advancements in superpower computing. They formed the Advanced Research Projects Agency (ARPA) in the year 1957. In those they still had powerful computers, but they weren’t able to talk or communicate with one another. In 1966 Lawrence G. Roberts (From MIT) proposed the first computer network which was named the ARPANET. The US Department of Defense (DoD) funded the venture and it took them 3 years to implement the network. The ARPANET team rewarded the DoD by establishing the Network Control Protocol (NCP), the first host to host protocol, which made possible for the university and the research center PC’s to communicate with one another.

With the success of the NCP, telco major AT&T installed the first cross country link between UCLA and BBN. It was a humble beginning and by 1973 hundreds of computers were talking to one another.

The real big breakthrough came in the year 1982 when the TCP/IP standard was established by Vint Cerf and Bob Kahn. Based on this development, the Domain Name System was established and by 1984 there were over 1000 hosts registered.

This was the backbone of the current day Internet. It was called NSFNET originally and with multiplying hosts it was becoming difficult to manage. By 1991 there were over a hundred thousand hosts and the system was getting out of control. There was nobody incharge and there was utter chaos all around.

In 1991, Tim Berners Lee created hyperlinks. He invented the whole protocol that made links communicate with one another and the World Wide Web was born. Telnet, email and many other services started using the networks.

In 1993, Marc Anderson and his friends wanted to see what was on the Internet, so they developed a new program called the NCSA Mosaic at the University of Illinois based on Berners Lee’s ideas. (NCSA stands for National Center for Supercomputing Applications)

Mosaic was the catalyst that caused the internet to explode. Nearly 200 million hosts were in use by the end of the decade and more than 1 billion users were using it.

This was not the end of it. Mobile phones, PDAs, GPS, Cars etc started connecting to the internet and the number of users began growing beyond numbers that we can write down or calculate.

It all started with basic HTML pages and hungry scientists created more and more advanced technologies whose powers were unbelievable. JSPs and Servlets just changed the landscape catastrophically and here we are, studying them to become better J2EE web programmers!!!

History of JSP & Servlets

The Internet's original purpose was to access and copy files from one computer to another. While TCP/IP provided a highway layer, the File Transfer Protocol (FTP) specification provided a standard way to exchange those files. It defined a way of shuttling them back and forth, but said nothing about looking at the content. HyperText Markup Language (HTML) allowed us to see the documents on the Internet. FTP can transmit HTML files just as easily as HTTP can. But we use Hypertext Transfer Protocol (HTTP) to act as an FTP specifically for HTML documents because it is a stateless protocol which makes having many short connections more efficient.
HTTP is the plumbing that connects the various computers. Now it is time to discuss about the fluid that flows through it “JSP & Servlets”

Note: JSP & Servlets arent the only technologies that are used in J2EE applications. Struts, Hibernate, Springs etc are other technologies that are used in J2EE Web applications. But, don't worry about them because they arent in the exam.

Using HTTP and HTML people were able to view/browse files and contents on a remote server. This is very useful, but people wanted live data. This is where the CGI (Common Gateway Interface) specification helped us. It helped us connect to databases and display stuff on the fly. The CGI specification was a major breakthrough in Web Application Development. The CGI standards made sure that the same CGI program worked on different Web servers.

CGI became the bread and butter of web developers. It was the most common means of displaying dynamic content on the internet. Though it was good, it wasn't good enough. It was not able to handle the performance requirements of the bursting Internet users. It was literally too much for it.

If you are asking me why CGI couldn't handle the load, the answer is simple. CGI spawned a separate process for every request that it receives. This design was able to sustain during off-peak hours but ate off server resources during peak loads which was eventually too much for it.
With growing numbers of users of web applications, scalability became a key consideration which wasn't CGI’s Middle Name and hence people started exploring other options.

Many CGI derivatives came up as server-side programming solutions that implement business logic, including ASP, ColdFusion, PHP, and Perl. Java surpassed them all due to portability and its object oriented programming design.

Alas, he we are, learning JSPs and Servlets that are the children of the Java Family which make our lives all the more easier in the world of Web Development.

Java was conceptualized in 1991 but it wasn't in the internet programming world until 1997. Servlets were the alternative to CGI and were released in 1997. Unlike CGI, which starts a process for each request, Servlets just spawn a new thread. Servlets had a better or rather efficient architecture which was able to handle the loads of the internet.

Though Servlets were awesome when compared to CGI, they still had some issues when it came to displaying dynamic content on a web page. Thankfully, Sun released the JSP (Java Server Pages) specifications in 1998, which solved all our UI woes. JSPs enabled programmers to display dynamic HTML content that could also use Java features. The combination of JSPs and Servlets was just what the Doctor Prescribed and it just revolutionized the Web Programming industry.
That's it for the history lesson. Now we are all set to dive deep into the world of magical Servlets and JSPs.

Previous Chapter: Introduction to the SCWCD Exam

Next Chapter: Web Servers & Servlet Containers

Sunday, February 27, 2011

Introduction to the Web Component Developer Exam

Well, let me begin by congratulating you on your decision to get yourself a Web Component Developer certification. It is a good decision and the subsequent series of articles in my blog would help you attain your goal.

Any goal needs a start and well, this chapter is the starting point on our journey towards SCWCD certification.

So, lets get started!!!

Introduction to the Web Component Developer Certification:

The Sun Certified Web Component Developer (SCWCD) certification covers the basic Web development concepts “Servlets” and “Java Server Pages (JSP)”

Servlets are classes that look like those you use in basic Java Programming, except they extend special purpose classes that enable them to respond to Web server requests. JSP pages extend servlet technology with a simple HTML (or XML) syntax. You can also include normal Java statements inside JSP files.

The servlet container actually compiles JSP pages into a servlet the first time it is requested.

Official Definition of a JSP:

What good would this series of articles be if we dont look at the official definition of the technologies we are going to get ourselves certified with.

“JavaServer Pages is the Java 2 Platform, Enterprise Edition (J2EE) technology for building applications for generating dynamic Web content, such as HTML, DHTML, XHTML and XML. The JavaServer Pages technology enables the easy authoring of web pages that create dynamic content with maximum power and flexibility.”

Benefits of using JSPs for developing Web Applications:

There are a lot of significant benefits of using JSPs for developing our Web Applications. They are:
a. Write Once, Run Anywhere
b. Code Re-use
c. Support for Scripting
d. Supports Actions
e. Supports both Static & Dynamic Content
f. Supports N-tier Enterprise Application Architecture
g. Superior Quality Documentation & Examples (All over the internet)
h. Reusable Tag Libraries

Official Definition of Servlets:

We saw the official definition of JSPs and now it is time to take a look at the same for Servlets.
Servlet is a Java technology based Web component, managed by a container that generates dynamic content. Containers, also called as Servlet Engines, are Web Server extensions that provide the Servlet Functionality. Servlets interact with other web clients like JSPs via a request/response mechanism implemented by the Servlet Container

Benefits of using Servlets for developing Web Applications:

Servlets are an integral part of any J2EE Web application. The key benefits of using Servlets in our web applications are:
a. They are faster than CGI scripts because each CGI script produces an entirely new process that takes a lot of time to execute, whereas a servlet creates only a new thread.
b. Servlet API is standard and available easily on the internet (like JSPs)
c. Servlets have the advantages like ease of development & platform independence (like Java)
d. They can access all the J2SE and J2EE APIs
e. Can take the full advantage & capabilities of the Java programming langauge
As you can see, there are numerous advantages of using the Servlet & JSP technologies. This is exactly why numerous organizations use them as a staple part of their J2EE application development work.

Exam Trivia:
How would you convince your employer that you are capable in the use of JSP and Servlets and can be a useful addition to their workforce?
The answer is simple and a No Brainer – Get yourself SCWCD Certified!!!

The SCWCD Exam:

The SCWCD Exam is a 90 minute exam in which the candidate is expected to answer 60 questions. A Majority of them (almost 90%) are multiple choice questions. You are expected to choose all the correct answers of a question in order to get the full marks for answering that question. If let’s say, a question has 3 right answers and you choose only 2, you will not get full points for that question.

The Exam is moderately difficult or even significantly difficult for novice programmers. You need to get atleast 37 of the 60 questions right in order to pass the exam.

Preparing for the SCWCD Exam:

First and foremost requirement to pass the exam is to prepare for the exam properly. You cant pass the exam by just going through exam questions/answers dumps over the internet. A dedicated preparation is essential. The sequence of articles in my blog would help you do that. At the same time, you need a computer that has Java in it and you should get some hands on practice in coding components that are covered in the SCWCD exam.

You’ll need the following in your computer:

• Install Java (V 1.4 or higher)
• Install Tomcat V4.0 or higher (It is a free Web Server)
• Download the JSP 1.2 and Servlets 2.3 specifications

Once you are done with this, you are all set to get yourself a SCWCD Certification.

Well, thats it for this chapter. Lets dive into concepts you need to know for the exam, one by one in the subsequent chapters.

Next Chapter: Servlet & JSP History

Saturday, February 26, 2011

Some Last Words Before you take the SCJP Exam

Thank you for coming this far in the SCJP exam series in my blog. If you have read through and understood the articles in the SCJP exam series, you are now well equipped to crack the SCJP exam. Let me sign-off on this SCJP exam series with a few last words.

So, as usual, lets get started!!!

What This Series Is Not

This series of blog articles is not a beginners guide or a definitive guide to the Java programming language. The articles are written under the assumption that you are someone who knows a little bit of Java and are someone who aims at becoming SCJP certified. This is not the Java Complete reference and there are many advanced topics like RMI (Remote Method Invocation), JDBC (Database Connectivity) etc that we havent covered because, they arent on the exam.

Some Tips

Once you have completed reading all the chapters in this SCJP series, I suggest you do the following:
a. Re-visit all the quick review chapters and go through all the important points about the topics we have covered
b. Re-read all the Exam Tips that are present as Quotes in each chapter and remember them
c. Have someone quiz you with random questions from the self-test chapters
d. Re-visit the self-test chapters and try to answer all the questions (Without checking the answers) (I know you are mumbling Of Course pal, I know that. But still, it is my duty isnt it?)
e. Write java code and I mean lots of it. Coding is the best way to learn the language and nothing can beat it.

The Last Exam Tip:

It is a good practice to review all your answers once you are done answering the questions. It is also important that, you do not change your answers during the review, unless you know that your answer is wrong for sure. Only change an answer when you feel you may have misread or misinterpreted the question the first time. Nervousness may make you second-guess every answer and talk yourself out of a correct one.

Tips on Cracking the Exam

There are 72 questions on the 310-065 (SCJP Java 6) exam. You will need to get at least 47 of them correct to pass—around 65%. You are given over three hours to complete the exam. This information is subject to change. Always check with the Sun official website before taking the exam, at www.suned.sun.com.

Some More Tips:

a. You can answer questions in any order. So if you feel you arent able to answer a question, don't waste too much time on that question, just move on to the next one and you can come back and answer this bad boy later
b. Be careful & cautious on the code examples. Check for syntax errors first: count curly braces, semicolons, and parenthesis and then make sure there are as many left ones as right ones. Look for capitalization errors and other such syntax problems before trying to figure out what the code does.
c. The code may look almost fine and you may be tempted to choose an answer as the possible output, but the code might be missing a closing paranthesis which means it wouldn't compile and you would miss a easy no-brainer in your hurry to answer the question

Well, thank you again for being a patron of my articles and I sincerely hope they were useful and you pass the SCJP exam with flying colors.

All the very best.

Previous Chapter: Other Topics of Importance

Next Chapter: None. This is the last chapter in the SCJP Series. You can go to the first article of this series, if you want by "clicking here"

Chapter 62: Other Topics of Importance

So far, over the past chapters, we have covered a lot of topics that feature in the SCJP exam syllabus. Apart from this, there are a few other minor topics that you need to know which might feature in the exam questions.

Before we start, I have to tell you that this is going to be the penultimate chapter in this SCJP series and well, I am really glad that both of us have made it so far.

So without much delays, lets get started!!!

Compiling Java Programs

The javac command is used to invoke Java’s compiler and compile a Java source file.
A typical invocation of the javac command would look like below:

javac [options] [source files]

Both the [options] and the [source files] are optional parts of the command, and both allow multiple entries. The following are both legal javac commands:

javac -help
javac ClassName.java OneMoreClassName.java

The first invocation doesn’t compile any files, but prints a summary of valid options. The second invocation passes the compiler two .java files to compile (ClassName.java and OneMoreClassName.java). Whenever you specify multiple options and/or files they should be separated by spaces.

This command would create the .class files that would be require to run the java progam.

Compiling with -d

By default, the compiler puts a .class file in the same directory as the .java source file. This is fine for very small projects, but once you’re working on a project of any size at all, you’ll want to keep your .java files separated from your .class files. The -d option lets you tell the compiler in which directory to put the .class files it generates (d is for destination).

Lets take a look at two example commands:

javac -d classes source/MyTestClass.java
javac -d ../classes com/scjp/test/MyTestClass.java

Example 1 – Compile file named “MyTestClass.java” that is present inside the “source” sub-directory of the current directory and put the .class file in the “classes” sub-directory of the current directory

Example 2 – Compile the file named “MyTestClass.java” that is present in the following directory hierarchy “com/scjp/test/” from the current directory and put the .class file in the folder “classes” that is present one level above the current directory

One thing you must know about the -d option is that if the destination directory you specify doesn’t exist, you’ll get a compiler error. If, in the previous example, the classes directory did NOT exist, the compiler would say something like:

java:5: error while writing MyTestClass: classes/ MyTestClass.class (No such file or directory)

Running Java Programs

The java command is used to invoke the Java virtual machine. This command invokes the JVM and asks it to run the program that is specified in the argument.

java [options] className [args]

The [options] and [args] parts of the java command are optional, and they can both have multiple values. You must specify exactly one class file to execute, and the java command automatically assumes that you’re going to send only a .class file, so you don’t have to specify the .class extension on the command line. Here’s an example:

java MyTestClass 1 2 3

The above command invokes the .class file of our test class MyTestClass and passes 1, 2 and 3 as command line arguments.

For fun, just assume that the hypothetical code inside MyTestClass expects 3 command line arguments. Don't worry, am not going to bore you with the code of that class here…

Using System Properties

For the exam you need to know how to access the properties of the system in which you are running your programs.

Java has a class called java.util.Properties that can be used to access a system’s basic information like the current versions of the operating system, the Java compiler, and the Java virtual machine. In addition to providing such default information, you can also add and retrieve your own properties. Ex:

import java.util.*;
public class TestProperties {
public static void main(String[] args) {
Properties p = System.getProperties();
p.setProperty("props", "value");
p.list(System.out);
}
}

If this file is compiled and invoked as follows:
java -DcompileTimeProp=compileTimeVal TestProperties

You’ll get something like this:
...
os.name=Windows XP
props=value
...
java.specification.vendor=Sun Microsystems Inc.
user.language=en
java.version=1.6.0_05
...
compileTimeProp=compileTimeVal
...
There will be a lot more values printed on the console. To save space I just put out the information we are interested in…

Two name=value properties were added to the system’s properties: props=value was added via the setProperty method, and compileTimeProp=compileTimeVal was added via the -D option at the command line. When using the -D option, if your value contains white space the entire value should be placed in quotes like this:
java -DcompileTimeProp="compileTimeVal take 2" TestProperties

To repeat - when you use -D, the name=value pair must follow immediately, no spaces allowed.

The getProperty() method is used to retrieve a single property. It can be invoked with a single argument (a String that represents the name (or key)), or it can be invoked with two arguments, (a String that represents the name (or key), and a default String value to be used as the property if the property does not already exist). In both cases, getProperty() returns the property as a String.

Using Command-Line Arguments

You would probably know to handle or rather use command line arguments in your java program. But, just for the sake of completeness am putting out a simple example that handles command line arguments in the code. For the exam you need to know this (Why else would I bore you with such miniscule topics :-))

public class CommandLineArgExample {
public static void main(String[] args) {
int x = 0;
for(String s : args)
System.out.println(x++ + " element = " + s);
}
}

compiled and then invoked as follows

java CommandLineArgExample 1 A
the output will be
0 element = 1
1 element = A

Like all arrays, args index is zero based. Arguments on the command line directly follow the class name. The first argument is assigned to args[0], the second argument is assigned to args[1], and so on.

Exam Tip:
The main() method signature can be tweaked a little bit. So don't be confused or surprised if you see something you arent used to.
The following are all legal declarations for main():
static public void main(String[] args)
public static void main(String... x)
static public void main(String king_kong[])


Static Imports

Static imports is a new feature that was introduced as of Java 5. You already know that an import statement is required to include code from other java classes and APIs that are not part of the current class you are coding. These static imports were implemented to provide greater keystroke-reduction for programmers. Though, not many of us appreciate it, nonetheless, you may end up getting a question on this topic and hence it is my duty to cover this topic.

Without static imports:

public class RegularClassCode {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
}
}

With static imports:

import static java.lang.System.out;
import static java.lang.Integer.*;
public class UseStaticImportsCode {
public static void main(String[] args) {
out.println(MAX_VALUE);
}
}

Both classes produce the same output:
2147483647

I guess, you already figured out whats happening here. By importing the System class, we were able to directly invoke its static methods. So instead of saying System.out.println() we just said out.println().

I personally am a little skeptical about the usefulness of this feature because, though we don't have to write System.out.println() everytime, if a new programmer who doesn't know what static imports is (cant expect everyone to know everything, isnt it?) opens up your code, he’ll be confused as to how in the hell did this guy print stuff on the console without using System.out.println() method.

There are a couple of rules for using static imports:

• You must say import static; you can’t say static import.
• Watch out for ambiguously named static members. For instance, if you do a static import for both the Integer class and the Long class, referring to MAX_VALUE will cause a compiler error, since both Integer and Long have a MAX_VALUE constant, and Java won’t know which MAX_VALUE you’re referring to.
• You can do a static import on static object references, constants (remember they’re static and final), and static methods.

Previous Chapter: Self Test - Chapters 55 to 61

Next Chapter: Some last words before you take the SCJP Certification

Self Test: Chapters 55 to 61

This is going to be the last self test chapter in our SCJP Exam series. The following questions will help you judge your expertise about threads that you learnt just now.

Questions:

Question 1

The following block of code creates a Thread using a Runnable target:
Runnable r = new MyRunnable();
Thread SimpleThreadExample = new Thread(r);

Which of the following classes can be used to create the target, so that the preceding code compiles correctly?
A. public class MyRunnable extends Runnable{public void run(){}}
B. public class MyRunnable extends Object{public void run(){}}
C. public class MyRunnable implements Runnable{public void run(){}}
D. public class MyRunnable implements Runnable{void run(){}}
E. public class MyRunnable implements Runnable{public void start(){}}

Question 2

Given:

3. class SimpleThreadExample extends Thread {

4. public static void main(String [] args) {

5. SimpleThreadExample t = new SimpleThreadExample();

6. Thread x = new Thread(t);

7. x.start();

8. }

9. public void run() {

10. for(int i=0;i<3;++i) {

11. System.out.print(i + "..");

12. }

13. }

14. }



What is the result of this code?

A. Compilation fails

B. 1..2..3..

C. 0..1..2..3..

D. 0..1..2..

E. An exception occurs at runtime





Question 3



Given:

3. class Test {

4. public static void main(String [] args) {

5. printStuff(args);

6. }

7. public static void printStuff(String[] lines) {

8. for(int i=0;i < lines.length;i++){

9. System.out.println(lines[i]);

10. Thread.currentThread().sleep(1000);

11. }

12. }

13. }



The static method Thread.currentThread() returns a reference to the currently executing Thread object. What is the result of this code?

A. Each String in the array lines will output, with a 1-second pause between lines

B. Each String in the array lines will output, with no pause in between because this method is not executed in a Thread

C. Each String in the array lines will output, and there is no guarantee there will be a pause because currentThread() may not retrieve this thread

D. This code will not compile

E. Each String in the lines array will print, with at least a one-second pause between lines



Question 4

Assume you have a class that holds two private variables: x and y. Which of the following pairs can prevent concurrent access problems in that class? (Choose all that apply.)
A. public int read(){return x+y;}
B. public void set(int x, int y){this.x=x;this.y=y;}
C. public synchronized int read(){return x+y;}
D. public synchronized void set(int x, int y){this.x=x;this.y=y;}
E. public int read(){synchronized(x){return x+y;}}
F. public void set(int x, int y){synchronized(x){this.x=x;this.y=y;}}
G. public int read(){synchronized(x){return x+y;}}
H. public void set(int x, int y){synchronized(y){this.x=x;this.y=y;}}
I. public synchronized(this) int read(){return x+y;}
J. public synchronized(this) void set(int x, int y){this.x=x;this.y=y;}
K. public int read(){synchronized(this){return x+y;}}
L. public void set(int x, int y){synchronized(this){this.x=x;this.y=y;}}

Question 5

Given:
1. public class TestWaitMethod {
2. public static void main(String [] args) {
3. System.out.print("1 ");
4. synchronized(args){
5. System.out.print("2 ");
6. try {
7. args.wait();
8. }
9. catch(InterruptedException e){}
10. }
11. System.out.print("3 ");
12. }
13. }

What is the result of trying to compile and run this program?
A. It fails to compile because the IllegalMonitorStateException of wait() is not dealt with in line 7
B. 1 2 3
C. 1 3
D. 1 2
E. At runtime, it throws an IllegalMonitorStateException when trying to wait
F. It will fail to compile because it has to be synchronized on the this object

Question 6

Assume the following method is properly synchronized and called from a thread A on an object B:
wait(2000);

After calling this method, when will the thread A become a candidate to get another turn at the CPU?
A. After object B is notified, or after two seconds
B. After the lock on B is released, or after two seconds
C. Two seconds after object B is notified
D. Two seconds after lock B is released

Question 7

Which are true? (Choose all that apply.)
A. The notifyAll() method must be called from a synchronized context
B. To call wait(), an object must own the lock on the thread
C. The notify() method is defined in class java.lang.Thread
D. When a thread is waiting as a result of wait(), it releases its lock
E. The notify() method causes a thread to immediately release its lock
F. The difference between notify() and notifyAll() is that notifyAll() notifies all waiting threads, regardless of the object they’re waiting on

Question 8

Given the scenario: This class is intended to allow users to write a series of messages, so that each message is identified with a timestamp and the name of the thread that wrote the message:
public class MyErrorLoggingUtilClass {
private StringBuilder contents = new StringBuilder();
public void log(String message) {
contents.append(System.currentTimeMillis());
contents.append(": ");
contents.append(Thread.currentThread().getName());
contents.append(message);
contents.append("\n");
}
public String getLogMessages() { return contents.toString(); }
}

How can we ensure that instances of this class can be safely used by multiple threads?
A. This class is already thread-safe
B. Replacing StringBuilder with StringBuffer will make this class thread-safe
C. Synchronize the log() method only
D. Synchronize the getLogMessages() method only
E. Synchronize both log() and getLogMessages()
F. This class cannot be made thread-safe

Question 9

Given:
public static synchronized void main(String[] args) throws
InterruptedException {
Thread t = new Thread();
t.start();
System.out.print("X");
t.wait(10000);
System.out.print("Y");
}

What is the result of this code?
A. It prints X and exits
B. It prints X and never exits
C. It prints XY and exits almost immeditately
D. It prints XY with a 10-second delay between X and Y
E. It prints XY with a 10000-second delay between X and Y
F. The code does not compile
G. An exception is thrown at runtime

Question 10

Given:
class SimpleThreadExample extends Thread {
SimpleThreadExample() {
System.out.print(" SimpleThreadExample");
}
public void run() {
System.out.print(" aaa");
}
public void run(String s) {
System.out.print(" bbb");
}
}
public class TestThreads {
public static void main (String [] args) {
Thread t = new SimpleThreadExample() {
public void run() {
System.out.print(" ccc");
}
};
t.start();
} }

What is the result?
A. ccc
B. SimpleThreadExample ccc
C. SimpleThreadExample aaa
D. ccc aaa
E. ccc aaa bbb
F. aaa ccc
G. Compilation fails
H. An exception is thrown at runtime

Question 11

Given:
public class ExampleThread {
synchronized void a() { doSomething(); }
static synchronized void b() { doSomething(); }
static void doSomething() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
public static void main(String[] args) {
final ExampleThread x = new ExampleThread();
final ExampleThread y = new ExampleThread();
Runnable runnable = new Runnable() {
public void run() {
int option = (int) (Math.random() * 4);
switch (option) {
case 0: x.a(); break;
case 1: x.b(); break;
case 2: y.a(); break;
case 3: y.b(); break;
}
}
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
}
}



Which of the following pairs of method invocations could NEVER be executing at the same time? (Choose all that apply.)
A. x.a() in thread1, and x.a() in thread2
B. x.a() in thread1, and x.b() in thread2
C. x.a() in thread1, and y.a() in thread2
D. x.a() in thread1, and y.b() in thread2
E. x.b() in thread1, and x.a() in thread2
F. x.b() in thread1, and x.b() in thread2
G. x.b() in thread1, and y.a() in thread2
H. x.b() in thread1, and y.b() in thread2

Question 12

Given:
public class MultipleThreadExample {
static Thread cena, orton;
public static void main(String[] args) {
cena = new Thread() {
public void run() {
System.out.println("A");
try {
orton.sleep(1000);
} catch (Exception e) {
System.out.println("B");
}
System.out.println("C");
}
};
orton = new Thread() {
public void run() {
System.out.println("D");
try {
cena.wait();
} catch (Exception e) {
System.out.println("E");
}
System.out.println("F");
}
};
cena.start();
orton.start();
}
}


Which letters will eventually appear somewhere in the output? (Choose all that apply.)
A. A
B. B
C. C
D. D
E. E
F. F
G. The answer cannot be reliably determined
H. The code does not compile

Question 13

Given:
3. public class Runner implements Runnable {
4. void go(long id) {
5. System.out.println(id);
6. }
7. public static void main(String[] args) {
8. System.out.print(Thread.currentThread().getId() + " ");
9. // insert code here
10. }
11. public void run() { go(Thread.currentThread().getId()); }
12. }

And given the following five fragments:
I. new Runner().run();
II. new Runner().start();
III. new Thread(new Runner());
IV. new Thread(new Runner()).run();
V. new Thread(new Runner()).start();

When the five fragments are inserted, one at a time at line 9, which are true? (Choose all that apply.)
A. All five will compile
B. Only one might produce the output 4 4
C. Only one might produce the output 4 2
D. Exactly two might produce the output 4 4
E. Exactly two might produce the output 4 2
F. Exactly three might produce the output 4 4
G. Exactly three might produce the output 4 2

Question 14

Given:
3. public class Awesome implements Runnable {
4. public static void main(String[] args) {
5. Thread t = new Thread(new Awesome());
6. t.start();
7. System.out.print("a1 ");
8. t.join();
9. System.out.print("a2 ");
10. }
11. public void run() {
12. System.out.print("b1 ");
13. System.out.print("b2 ");
14. }
15. }

Which are true? (Choose all that apply.)
A. Compilation fails
B. The output could be b1 b2 a1 a2
C. The output could be a1 a2 b1 b2
D. The output could be a1 b1 b2 a2
E. The output could be a1 b1 a2 b2
F. An exception is thrown at runtime

Question 15

Given:

3. class Friends {

4. static long flag = 0;

5. // insert code here

6. if(flag == 0) flag = id;

7. for(int x = 1; x < 3; x++) {

8. if(flag == id) System.out.print("yo ");

9. else System.out.print("Friend ");

10. }

11. }

12. }

13. public class FriendsHangOut implements Runnable {

14. static Friends d;

15. public static void main(String[] args) {

16. new FriendsHangOut().go();

17. }

18. void go() {

19. d = new Friends();

20. new Thread(new FriendsHangOut()).start();

21. new Thread(new FriendsHangOut()).start();

22. }

23. public void run() {

24. d.chat(Thread.currentThread().getId());

25. }

26. }






And given these two fragments:

I. synchronized void chat(long id) {

II. void chat(long id) {



When fragment I or fragment II is inserted at line 5, which are true? (Choose all that apply.)

A. An exception is thrown at runtime

B. With fragment I, compilation fails

C. With fragment II, compilation fails

D. With fragment I, the output could be yo Friend Friend yo

E. With fragment I, the output could be Friend Friend yo yo

F. With fragment II, the output could be yo Friend Friend yo





Answers:

Answer 1
C is correct. The class implements the Runnable interface with a legal run() method.

A is incorrect because interfaces are implemented, not extended. B is incorrect because even though the class has a valid public void run() method, it does not implement the Runnable interface. D is incorrect because the run() method must be public. E is incorrect because the method to implement is run(), not start().

Answer 2
D is correct. The thread SimpleThreadExample will start and loop three times (from 0 to 2).

A is incorrect because the Thread class implements the Runnable interface; therefore, in line 5, Thread can take an object of type Thread as an argument in the constructor (this is NOT recommended). B and C are incorrect because the variable i in the for loop starts with a value of 0 and ends with a value of 2.

Answer 3
D is correct. The sleep() method must be enclosed in a try/catch block, or the method printStuff() must declare it throws the InterruptedException.

E is incorrect, but it would be correct if the InterruptedException was dealt with (A is too precise). B is incorrect (even if the InterruptedException was dealt with) because all Java code, including the main() method, runs in threads. C is incorrect. The sleep() method is static, it always affects the currently executing thread.

Answer 4
B and F are correct. By marking the methods as synchronized, the threads will get the lock of the this object before proceeding. Only one thread will be setting or reading at any given moment, thereby assuring that read() always returns the addition of a valid pair.

A is incorrect because it is not synchronized; therefore, there is no guarantee that the values added by the read() method belong to the same pair. C and D are incorrect; only objects can be used to synchronize on. E fails—it is not possible to select other objects (even this) to synchronize on when declaring a method as synchronized.

Answer 5
D is correct. 1 and 2 will be printed, but there will be no return from the wait call because no other thread will notify the main thread, so 3 will never be printed. It’s frozen at line 7.

A is incorrect; IllegalMonitorStateException is an unchecked exception. B and C are incorrect; 3 will never be printed, since this program will wait forever. E is incorrect because IllegalMonitorStateException will never be thrown because the wait() is done on args within a block of code synchronized on args. F is incorrect because any object can be used to synchronize on and this and static don’t mix.

Answer 6
A is correct. Either of the two events will make the thread a candidate for running again.

B is incorrect because a waiting thread will not return to runnable when the lock is released, unless a notification occurs. C is incorrect because the thread will become a candidate immediately after notification. D is also incorrect because a thread will not come out of a waiting pool just because a lock has been released.

Answer 7
A is correct because notifyAll() (and wait() and notify()) must be called from within a synchronized context. D is a correct statement.

B is incorrect because to call wait(), the thread must own the lock on the object that wait() is being invoked on, not the other way around. C is wrong because notify() is defined in java.lang.Object. E is wrong because notify() will not cause a thread to release its locks. The thread can only release its locks by exiting the synchronized code. F is wrong because notifyAll() notifies all the threads waiting on a particular locked object, not all threads waiting on any object.

Answer 8
E is correct. Synchronizing the public methods is sufficient to make this safe, so F is false. This class is not thread-safe unless some sort of synchronization protects the changing data.

B is not correct because although a StringBuffer is synchonized internally, we call append() multiple times, and nothing would prevent two simultaneous log() calls from mixing up their messages. C and D are not correct because if one method remains unsynchronized, it can run while the other is executing, which could result in reading the contents while one of the messages is incomplete, or worse.

Answer 9
G is correct. The code does not acquire a lock on t before calling t.wait(), so it throws an IllegalMonitorStateException. The method is synchronized, but it’s not synchronized on t so the exception will be thrown. If the wait were placed inside a synchronized(t) block, then the answer would have been D.

Answer 10
B is correct. The first line of main we’re constructing an instance of an anonymous inner class extending from SimpleThreadExample. So the SimpleThreadExample constructor runs and prints SimpleThreadExample. Next, main() invokes start() on the new thread instance, which causes the overridden run() method (the run() method in the anonymous inner class) to be invoked.

Answer 11

A, F, and H. A is a right answer because when synchronized instance methods are called on the same instance, they block each other. F and H can’t happen because synchronized static methods in the same class block each other, regardless of which instance was used to call the methods. (An instance is not required to call static methods; only the class.)

C could happen because synchronized instance methods called on different instances do not block each other. B, D, E, and G could all happen because instance methods and static methods lock on different objects, and do not block each other.

Answer 12
A, C, D, E, and F are correct. This may look like cena and orton are battling to cause the other to sleep() or wait()—but that’s not the case. Since sleep() is a static method, it affects the current thread, which is cena (even though the method is invoked using a reference to orton). That’s misleading but perfectly legal, and the Thread cena is able to sleep with no exception, printing A and C (after at least a 1-second delay). Meanwhile orton tries to call cena.wait()—but orton has not synchronized on cena, so calling cena.wait() immediately causes an IllegalMonitorStateException, and so orton prints D, E, and F. Although the order of the output is somewhat indeterminate (we have no way of knowing whether A is printed before D, for example) it is guaranteed that A, C, D, E, and F will all be printed in some order, eventually—so G is incorrect.

Answer 13
C and D are correct. Fragment I doesn’t start a new thread. Fragment II doesn’t compile. Fragment III creates a new thread but doesn’t start it. Fragment IV creates a new thread and invokes run() directly, but it doesn’t start the new thread. Fragment V creates and starts a new thread.

Answer 14
A is correct. The join() must be placed in a try/catch block. If it were, answers B and D would be correct. The join() causes the main thread to pause and join the end of the other thread, meaning "a2" must come last.

Answer 15
F is correct. With fragment I, the chat method is synchronized, so the two threads can’t swap back and forth. With either fragment, the first output must be yo.

Previous Chapter: Quick Review - Threads

Next Chapter: Other Topics of Importance

Quick Review: Chapters 55 to 61 (Threads)

This is going to be the last quick recap chapter in this SCJP Series. This will cover the important points about Threads.

Defining, Instantiating, and Starting Threads

* Threads can be created by extending Thread and overriding the public void run() method.

* 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.

* You can call start() on a Thread object only once. If start() is called more than once on a Thread object, it will throw a RuntimeException.

* It is legal to create many Thread objects using the same Runnable object as the target.

* When a Thread object is created, it does not become a thread of execution until its start() method is invoked. When a Thread object exists but hasn’t been started, it is in the new state and is not considered alive.

Transitioning Between Thread States

* Once a new thread is started, it will always enter the runnable state.

* The thread scheduler can move a thread back and forth between the runnable state and the running state.

* For a typical single-processor machine, only one thread can be running at a time, although many threads may be in the runnable state.

* There is no guarantee that the order in which threads were started determines the order in which they’ll run.

* There’s no guarantee that threads will take turns in any fair way. It’s up to the thread scheduler, as determined by the particular virtual machine implementation. If you want a guarantee that your threads will take turns regardless of the underlying JVM, you can use the sleep() method. This prevents one thread from hogging the running process while another thread starves.

* A running thread may enter a blocked/waiting state by a wait(), sleep(), or join() call.

* A running thread may enter a blocked/waiting state because it can’t acquire the lock for a synchronized block of code.

* When the sleep or wait is over, or an object’s lock becomes available, the thread can only reenter the runnable state. It will go directly from waiting to running (well, for all practical purposes anyway).

* A dead thread cannot be started again.

Sleep, Yield, and Join

* Sleeping is used to delay execution for a period of time, and no locks are released when a thread goes to sleep.

* A sleeping thread is guaranteed to sleep for at least the time specified in the argument to the sleep() method (unless it’s interrupted), but there is no guarantee as to when the newly awakened thread will actually return to running.

* The sleep() method is a static method that sleeps the currently executing thread’s state. One thread cannot tell another thread to sleep.

* The setPriority() method is used on Thread objects to give threads a priority of between 1 (low) and 10 (high), although priorities are not guaranteed, and not all JVMs recognize 10 distinct priority levels—some levels may be treated as effectively equal.

* If not explicitly set, a thread’s priority will have the same priority as the priority of the thread that created it.

* The yield() method may cause a running thread to back out if there are runnable threads of the same priority. There is no guarantee that this will happen, and there is no guarantee that when the thread backs out there will be a different thread selected to run. A thread might yield and then immediately reenter the running state.

* The closest thing to a guarantee is that at any given time, when a thread is running it will usually not have a lower priority than any thread in the runnable state. If a low-priority thread is running when a high-priority thread enters runnable, the JVM will usually preempt the running low-priority thread and put the high-priority thread in.

* When one thread calls the join() method of another thread, the currently running thread will wait until the thread it joins with has completed. Think of the join() method as saying, “Hey thread, I want to join on to your end. Let me know when you’re done, so I can enter the runnable state.”

Synchronization

* synchronized methods prevent more than one thread from accessing an object’s critical method code simultaneously.

* You can use the synchronized keyword as a method modifier, or to start a synchronized block of code.

* To synchronize a block of code, you must specify an argument that is the object whose lock you want to synchronize on.

* While only one thread can be accessing synchronized code of a particular instance, multiple threads can still access the same object’s unsynchronized code.

* When a thread goes to sleep, its locks will be unavailable to other threads.

* static methods can be synchronized, using the lock from the java.lang.Class instance representing that class.

Thread Communication

* The wait() method lets a thread say, “I got nothing to do, so put me in your waiting pool and notify me when something happens that I care about.”

* The notify() method is used to send a signal to one and only one of the threads that are waiting in that same object’s waiting pool.

* The notify() method can NOT specify which waiting thread to notify.

* The method notifyAll() works in the same way as notify(), only it sends the signal to all of the threads waiting on the object.

* All three methods—wait(), notify(), and notifyAll()—must be called from within a synchronized context! A thread invokes wait() or notify() on a particular object, and the thread must currently hold the lock on that object.

Deadlocks

* Deadlocking is when thread execution grinds to a halt because the code is waiting for locks to be removed from objects.

* Deadlocking can occur when a locked object attempts to access another locked object that is trying to access the first locked object. In other words, both threads are waiting for each other’s locks to be released; therefore, the locks will never be released!


Previous Chapter: Chapter 61 - Thread Interaction

Next Chapter: Self Test - Chapters 55 to 61

Friday, February 25, 2011

Chapter 61: Thread Interactions

The last thing we need to look at in our series of chapters on threads, is how threads can interact with one another to communicate about, among other things, their locking status. The Object class has three methods, wait(), notify(), and notifyAll() that help threads communicate about the status of an event that the threads care about.


This is exactly what we are going to see in this chapter.


So, lets get started!!!


Using Wait and Notify


For example, if one thread is a repair-car repair-car thread and one thread is a accept-car-for-service thread, the accept-car-for-service thread has to keep checking to see if there’s any car to accept for service. Using the wait and notify mechanism, the accept-car-for-service thread could check for cars, and if it doesn’t find any it can say, “Hey, I’m not going to waste my time checking for a car every few minutes. I’m going to go hang out, and when a customer drives in with a car for service, have him notify me so I can go back to runnable and do some work.” In other words, using wait() and notify() lets one thread put itself into a “waiting room” until some other thread notifies it that there’s a reason to come back out.


One key point to remember for the exam about wait/notify is this:


wait(), notify(), and notifyAll() must be called from within a synchronized context! A thread can’t invoke a wait or notify method on an object unless it owns that object’s lock.


Here we’ll present an example of two threads that depend on each other to proceed with their execution, and we’ll show how to use wait() and notify() to make them interact safely and at the proper moment.


Think of a computer-controlled Mechanic that repairs cars and the user comes to the garage to drop of his car to repair. The current version of the application has one thread, which loops, first getting the car from the user and then giving it to the mechanic for repair:


public void run(){

while(true){

// Get Car from user

// Analyse and identify faulty parts

// Fix em...

// Send user home happy...

}

}


This design is not optimal because the user can’t do anything while the mechanic is busy and while there are other parts to fix. We need to improve the situation.


A simple solution is to separate the processes into two different threads, one of them interacting with the user and another fixing the car. The user thread sends the instructions to the fixing thread and then goes back to interacting with the user immediately. The fixing thread receives the instructions from the user thread and starts directing the mechanic immediately. Both threads use a common object to communicate, which holds the current car being processed.
The following pseudocode shows this design:


public void keepUserEngagedLoop(){

while(true){

// Get car from user

// Pass car repair instructions to fixing thread

}

}


public void fixingLoop(){

while(true){

// Get car into garage

// start fixing it

}

}


The problem now is to get the fixing thread to process the car as soon as it is available. Also, the user thread should not disturb the car until it is sent to the garage. The solution is to use wait() and notify(), and also to synchronize some of the code.


The methods wait() and notify(), remember, are instance methods of Object. In the same way that every object has a lock, every object can have a list of threads that are waiting for a notification from the object. A thread gets on this waiting list by executing the wait() method of the target object. From that moment, it doesn’t execute any further instructions until the notify() method of the target object is called. If many threads are waiting on the same object, only one will be chosen (in no guaranteed order) to proceed with its execution. If there are no threads waiting, then no particular action is taken. Let’s take a look at some real code that shows one object waiting for another object to notify it:


1. class FirstThread {

2. public static void main(String [] args) {

3. SecondThread b = new SecondThread();

4. b.start();

5.

6. synchronized(b) {

7. try {

8. System.out.println("Waiting for b to complete...");

9. b.wait();

10. } catch (InterruptedException e) {}

11. System.out.println("Value is: " + b.value);

12. }

13. }

14. }

15.

16. class SecondThread extends Thread {

17. int value;

18.

19. public void run() {

20. synchronized(this) {

21. for(int i=0;i<10;i++) {

22. value += i;

23. }

24. notify();

25. }

26. }

27. }



This program contains two objects with threads: FirstThread contains the main thread and SecondThread has a thread that calculates the sum of all numbers from 0 through 9. As soon as line 4 calls the start() method, FirstThread will continue with the next line of code in its own class, which means it could get to line 11 before SecondThread has finished the calculation. To prevent this, we use the wait() method in line 9.


Notice in line 6 the code synchronizes itself with the object b, this is because in order to call wait() on the object, FirstThread must own a lock on b. For a thread to call wait() or notify(), the thread has to be the owner of the lock for that object. When the thread waits, it temporarily releases the lock for other threads to use, but it will need it again to continue execution. It’s common to find code like this:


synchronized(someObject) { // this has the lock on someObject

try {

someObject.wait();

// the thread releases the lock and waits

// To continue, the thread needs the lock,

// so it may be blocked until it gets it.

} catch(InterruptedException e){}

}



The preceding code waits until notify() is called on someObject.

synchronized(this) { notify(); }



This code notifies a single thread currently waiting on the this object. The lock can be acquired much earlier in the code, such as in the calling method. Note that if the thread calling wait() does not own the lock, it will throw an IllegalMonitorStateException. This exception is not a checked exception, so you don’t have to catch it explicitly. You should always be clear whether a thread has the lock of an object in any given block of code.

Notice in lines 7–10 there is a try/catch block around the wait() method. A waiting thread can be interrupted in the same way as a sleeping thread, so you have to take care of the exception:


try {

wait();

} catch(InterruptedException e) {

// Do something about it

}


In the car garage example, the way to use these methods is to have the fixing thread wait on the car to be available and the user thread to notify after it has finished giving the car. The fixing steps may comprise global steps, such as moving the car to the garage area, and a number of substeps, such as checking the engine, transmission. As an example they could be


int NumberOfCylindersInEngine;

int NumberOfGearsInTransmission;

Engine engineMake;

float[] tires;

etc..


It is important that the user thread does not modify the car details while the fixing thread is using them, so this reading and writing should be synchronized.


The resulting code would look like this:

class User extends Thread {

public void run(){

while(true){

// Get car from user

synchronized(this){

// identify details to fix the car

notify();

}

}

}

}


class Mechanic extends Thread {

User User; // assume this gets initialized

public void run(){

while(true){

synchronized(User){

try {

User.wait();

} catch(InterruptedException ie) {}

// Send Mechanic steps to fixing

}

}

}

}


The Mechanic thread, once started, will immediately go into the waiting state and will wait patiently until the User sends the first notification. At that point it is the User thread that owns the lock for the object, so the fixing thread gets stuck for a while. It’s only after the User thread abandons the synchronized block that the fixing thread can really start processing the Mechanic steps.


While one car is being processed by the mechanic, the user may interact with the system and specify another car to be serviced. When the user is finished with the car and it is time to repair it, the User thread attempts to enter the synchronized block, maybe blocking until the Mechanic thread has finished with the previous Mechanic steps. When the Mechanic thread has finished, it repeats the loop, going again to the waiting state (and therefore releasing the lock). Only then can the User thread enter the synchronized block and overwrite the Mechanic steps with the new ones.


Having two threads is definitely an improvement over having one, although in this implementation there is still a possibility of making the user wait. A further improvement would be to have many cars in a queue, thereby reducing the possibility of requiring the user to wait for the mechanic.


There is also a second form of wait() that accepts a number of milliseconds as a maximum time to wait. If the thread is not interrupted, it will continue normally whenever it is notified or the specified timeout has elapsed. This normal continuation consists of getting out of the waiting state, but to continue execution it will have to get the lock for the object:


synchronized(a){ // The thread gets the lock on 'a'

a.wait(5000); // Thread releases the lock and waits for notify

// only for a maximum of five seconds, then goes back to Runnable

// The thread reacquires the lock

// More code here

}


Exam Tip:
When the wait() method is invoked on an object, the thread executing that code gives up its lock on the object immediately. However, when notify() is called, that doesn’t mean the thread gives up its lock at that moment. If the thread is still completing synchronized code, the lock is not released until the thread moves out of synchronized code. So just because notify() is called doesn’t mean the lock becomes available at that moment
Using notifyAll( )

In most scenarios, it’s preferable to notify all of the threads that are waiting on a particular object. If so, you can use notifyAll() on the object to let all the threads come out of the waiting area and back to runnable. This is especially important if you have several threads waiting on one object, but for different reasons, and you want to be sure that the right thread (along with all of the others) gets notified.


notifyAll(); // Will notify all waiting threads


All of the threads will be notified and start competing to get the lock. As the lock is used and released by each thread, all of them will get into action without a need for further notification.


As we said earlier, an object can have many threads waiting on it, and using notify() will affect only one of them. Which one, exactly, is not specified and depends on the JVM implementation, so you should never rely on a particular thread being notified in preference to other threads.


In cases in which there might be a lot more waiting, the best way to do this is by using notifyAll(). Let’s take a look at this in some code. In this example, there is one class that figures out a stocks current price and many stock traders that are waiting to receive the current value. At any given moment many traders may be waiting.


1. class Trader extends Thread {

2. StockPriceAnalyzer c;

3.

4. public Trader(StockPriceAnalyzer calc) {

5. c = calc;

6. }

7.

8. public void run() {

9. synchronized(c) {

10. try {

11. System.out.println("Waiting for calculation...");

12. c.wait();

13. } catch (InterruptedException e) {}

14. System.out.println("Value is: " + c.value);

15. }

16. }

17.

18. public static void main(String [] args) {

19. StockPriceAnalyzer StockPriceAnalyzer = new StockPriceAnalyzer();

20. new Trader(StockPriceAnalyzer).start();

21. new Trader(StockPriceAnalyzer).start();

22. new Trader(StockPriceAnalyzer).start();

23. StockPriceAnalyzer.start();

24. }

25. }

26.

27. class StockPriceAnalyzer extends Thread {

28. int value;

29.

30. public void run() {

31. synchronized(this) {

32. for(int i=0;i<10;i++) {

33. value += i;

34. }

35. notifyAll();

36. }

37. }

38. }


The program starts three threads that are all waiting to receive the finished calculation (lines 18–24), and then starts the StockPriceAnalyzer with its calculation. Note that if the run() method at line 30 used notify() instead of notifyAll(), only one Trader would be notified instead of all the Traders.


Apologies for the crappy code inside the stock market prize analyzer class. I cant probably put code that calculates the current price of any share in such a small place. So I just put in some code that does addition in a loop. As long as you understand the concept and not curse me for the example I am good!!!


Using wait( ) in a Loop


Actually both of the previous examples (Mechanic/User and Trader/StockPriceAnalyzer) had a common problem. In each one, there was at least one thread calling wait(), and another thread calling notify() or notifyAll(). This works well enough as long as the waiting threads have actually started waiting before the other thread executes the notify() or notifyAll(). But what happens if, for example, the StockPriceAnalyzer runs first and calls notify() before the Traders have started waiting? This could happen, since we can’t guarantee what order the different parts of the thread will execute in. Unfortunately, when the Traders run, they just start waiting right away. They don’t do anything to see if the event they’re waiting for has already happened. So if the StockPriceAnalyzer has already called notifyAll(), it’s not going to call notifyAll() again—and the waiting Traders will keep waiting forever. This is probably not what the programmer wanted to happen. Almost always, when you want to wait for something, you also need to be able to check if it has already happened. Generally the best way to solve this is to put in some sort of loop that checks on some sort of conditional expressions, and only waits if the thing you’re waiting for has not yet happened. Here’s a modified, safer version of the earlier Car & Mechanic example:


class User extends Thread {

Mechanic Mechanic; // assume this gets initialized

public void run() {

while (true) {

Car car = getCarFromUser();

MechanicInstructions job = processCarForInstructions(shape);

Mechanic.addCarForRepair(job);

}

}

}



The User will still keep on looping forever, getting more cars from users, calculating new instructions for those cars, and sending them to the Mechanic. But now the logic for notify() has been moved into the addCarForRepair() method in the Mechanic class:


class Mechanic extends Thread {

List jobs = new ArrayList();

public void addCarForRepair(MechanicInstructions job) {

synchronized (jobs) {

jobs.add(job);

jobs.notify();

}

}

public void run() {

while (true) {

synchronized (jobs) {

// wait until at least one car is available

while (jobs.isEmpty()) {

try {

jobs.wait();

} catch (InterruptedException ie) { }

}

// If we get here, we know that jobs is not empty

MechanicInstructions instructions = jobs.remove(0);

// Send Mechanic steps to garage

}

}

}

}


A Mechanic keeps a list of the jobs it’s scheduled to do. Whenever an User adds a new job to the list, it calls the addCarForRepair() method and adds the new job to the list. Meanwhile the run() method just keeps looping, looking for any jobs on the list. If there are no jobs, it will start waiting. If it’s notified, it will stop waiting and then recheck the loop condition: is the list still empty? In practice this double-check is probably not necessary, as the only time a notify() is ever sent is when a new job has been added to the list. However, it’s a good idea to require the thread to recheck the isEmpty() condition whenever it’s been woken up, because it’s possible that a thread has accidentally sent an extra notify() that was not intended.


There’s also a possible situation called spontaneous wakeup that may exist in some situations; a thread may wake up even though no code has called notify() or notifyAll().What this means is, when your thread wakes up from a wait(), you don’t know for sure why it was woken up. By putting the wait() method in a while loop and re-checking the condition that represents what we were waiting for, we ensure that whatever the reason we woke up, we will re-enter the wait() if and only if the thing we were waiting for has not happened yet. In the Mechanic class, the thing we were waiting for is for the jobs list to not be empty. If it’s empty, we wait, and if it’s not, we don’t.


Note also that both the run() method and the addCarForRepair() method synchronize on the same object, the jobs list. This is for two reasons. One is because we’re calling wait() and notify() on this instance, so we need to synchronize in order to avoid an IllegalThreadState exception. The other reason is, the data in the jobs list is changeable data stored in a field that is accessed by two different threads. We need to synchronize in order to access that changeable data safely. Fortunately, the same synchronized blocks that allow us to wait() and notify() also provide the required thread safety for our other access to changeable data. In fact this is a main reason why synchronization is required to use wait() and notify() in the first place, you almost always need to share some mutable data between threads at the same time, and that means you need synchronization. Notice that the synchronized block in addCarForRepair() is big enough to also include the call to jobs.add(job,)which modifies shared data. And the synchronized block in run() is large enough to include the whole while loop—which includes the call to jobs.isEmpty(), which accesses shared data.


The moral of the story here is (again value education stuff) that when you use wait() and notify() or notifyAll(), you should almost always also have a while loop around the wait() that checks a condition and forces continued waiting until the condition is met. And you should also make use of the required synchronization for the wait() and notify() calls, to also protect whatever other data you’re sharing between threads. If you see code which fails to do this, there’s usually something wrong with the code, even if you have a hard time seeing what exactly the problem is.


Exam Tip:
The methods wait() , notify(), and notifyAll() are methods of only java.lang.Object, not of java.lang.Thread or java.lang.Runnable. Be sure you know which methods are defined in Thread, which in Object, and which in Runnable (just run(), so that’s an easy one). Of the key methods in Thread, be sure you know which are static—sleep() and yield(), and which are not static—join() and start()

Key Thread Methods

To wrap up this chapter, we will take a look at the important thread methods and then we will call it a day!!!


Methods in the Object Class:
a. wait()

b. notify()

c. notifyAll()



Methods in the Thread Class:
a. start()

b. yield()

c. sleep()

d. join



Methods in the Runnable Interface:
a. run()


That's it folks. We are done with Threads!!! Ugh, that was pretty long and hard. Wasn't it? :-)

Previous Chapter: Chapter 60 - Synchronization

Next Chapter: Quick Review - Threads

Chapter 60: Synchronization

We have been using the term synchronizing multiple times over the course of the previous chapters. We have never cared to stop and explain what the term synchronizing or synchronization means. Well, here we are. This full chapter is dedicated to synchronization and how to synchronize our code.

So, lets get started!!!

Why do we need Synchronization?

Threads are a powerful concept that we explained in the previous few chapters. Just as in the case of any programming scenario, the code works on a set of data and processes it. Lets imagine a scenario:

Assume that I have borrowed Rs. 10000/- from you and another Rs. 10000/- from an anonymous Mr. X last month. Now, both of you are chasing me for the money and I give you cheques worth the money I owe you guys, each worth Rs. 10000/- so, now I have given cheques worth Rs. 20000/- for payment. Unfortunately for you both, my account has a balance of only Rs. 12000/- and fortunately for me the banking application of my bank does not care about synchronization. So here is what will happen in a hypothetical situation wherein both the cheques are going to be submitted for payment at the same time.

Bank A (Your bank) and Bank B (Mr. X’s bank) have both submitted the cheques for payment to my bank today morning at two different branches.

A teller is processing your cheque at branch 1 and another teller is processing Mr. X’s cheque at branch 2. Both the tellers are simultaneously initiating the cheque clearance activity. Here is how it works:

Step 1: Teller 1 initiates a transfer at 10:30 AM and Teller 2 initiates a transfer at 10:30 AM as well
Step 2: Teller 1’s system checks my bank balance at 10:31 AM and approves the payment because my account has Rs. 12,000 and Teller 2’s system does the same at the same time and approves the payment because the money in my account is more than the value of the cheque I have given.
Step 3: Since both systems feel that there is enough balance in my account, they successfully make the payment.

2 cheques, each worth Rs. 10000/- got paid even though I had only Rs. 12000/- in my bank. Though I am happy about it, clearly the bank is not.

Guess what went wrong here?

There is no synchronization between the two tellers. Practically speaking, two tellers in two different branches don't need to talk to one another before processing a cheque but the banks application should handle such a situation.

All this happened because, the system allowed data related to one persons account to be accessed by two different processes(threads) and also allowed the data to be modified by both those processes at the same time.

This problem is known as a “race condition,” where multiple threads can access the same Car (typically an object’s instance variables), and can produce corrupted data if one thread “races in” too quickly before an operation that should be “atomic” has completed.

Practically speaking, only one of the cheques should have been cleared (whichever teller clicked “Transfer Funds” button first in milliseconds) and the other guys cheque must have bounced. This is exactly what would have happened if the first thread took a lock on the data and processed it, while all other threads that want access to the same data are in line “waiting”. So, by the time the second teller clicked “Transfer funds” his process would have to wait until Teller 1’s transfer is complete and then, the check balance logic would have come back stating “Hey buddy, this bum does not have enough cash to pay this cheque. Bounce this bad boy, will you?”
Now, I guess you know why we need synchronization (Only if you own a bank) but still, we now appreciate the need for synchronization. Lets now look at the details of implementation of this concept.

Preventing the Overpayment of Cheques:

So what can be done? The solution is actually quite simple. We must ensure that the two steps of the transfer—checking the balance and making the transfer—are never split apart. We need them to always be performed as one operation, step 1 and step 2! We call this an “atomic operation” because the operation, regardless of the number of actual statements (or underlying byte code instructions), is completed before any other thread code that acts on the same data.
You can’t guarantee that a single thread will stay running throughout the entire atomic operation. But you can guarantee that even if the thread running the atomic operation moves in and out of the running state, no other running thread will be able to work on the same data. In other words, If Teller 1 falls asleep after checking the balance, we can stop Teller 2 from checking the balance until after Teller 1 wakes up and completes her transfer.

So how do you protect the data? You must do two things:
• Mark the variables private.
• Synchronize the code that modifies the variables.

Remember, you protect the variables in the normal way using an access control modifier. It’s the method code that you must protect, so that only one thread at a time can be executing that code. You do this with the synchronized keyword.

We can solve all of Teller 2 and Teller 1’s problems by adding one word to the code. We mark the makeTransfer() method synchronized as follows:
private synchronized void makeTransfer(int amt) {
if (acct.getBalance() >= amt) {
System.out.println(Thread.currentThread().getName() +
" is going to Transfer");
try {
Thread.sleep(500);
} catch(InterruptedException ex) { }
acct.Transfer(amt);
System.out.println(Thread.currentThread().getName() +
" completes the transfer");
} else {
System.out.println("Not enough in account for "
+ Thread.currentThread().getName()
+ " to Transfer " + acct.getBalance());
}
}

Now we’ve guaranteed that once a thread (Teller 1 or Teller 2) starts the transfer process (by invoking makeTransfer()), the other thread cannot enter that method until the first one completes the process by exiting the method. The new output shows the benefit of synchronizing the makeTransfer() method:

Teller 2 is going to Transfer
Teller 2 completes the transfer
Teller 1 is going to Transfer
Teller 1 completes the transfer
Teller 2 is going to Transfer
Teller 2 completes the transfer
Teller 1 is going to Transfer
Teller 1 completes the transfer
Teller 2 is going to Transfer
Teller 2 completes the transfer
Not enough in account for Teller 1 to Transfer 0
Not enough in account for Teller 2 to Transfer 0
Not enough in account for Teller 1 to Transfer 0
Not enough in account for Teller 2 to Transfer 0
Not enough in account for Teller 1 to Transfer 0

Notice that now both threads, Teller 1 and Teller 2, always check the account balance and complete the transfer before the other thread can check the balance.

Synchronization and Locks

How does synchronization work? The Answer is simple “With locks”. Every object in Java has a built-in lock that only comes into play when the object has synchronized method code. When we enter a synchronized non-static method, we automatically acquire the lock associated with the current instance of the class whose code we’re executing. Acquiring a lock for an object is also known as getting the lock, or locking the object, locking on the object, or synchronizing on the object. We may also use the term monitor to refer to the object whose lock we’re acquiring. Technically the lock and the monitor are two different things, but here we refer to the same thing by those two words.

Since there is only one lock per object, if one thread has picked up the lock, no other thread can pick up the lock until the first thread releases or returns the lock. This means no other thread can enter the synchronized code until the lock has been released. Typically, releasing a lock means the thread holding the lock, in other words, the thread currently in the synchronized method exits the synchronized method. At that point, the lock is free until some other thread enters a synchronized method on that object. Remember the following key points about locking and synchronization:

• Only methods (or blocks) can be synchronized, not variables or classes.
• Each object has just one lock.
• Not all methods in a class need to be synchronized. A class can have both synchronized and non-synchronized methods.
• If two threads are about to execute a synchronized method in a class, and both threads are using the same instance of the class to invoke the method, only one thread at a time will be able to execute the method. The other thread will have to wait until the first one finishes its work. In other words, once a thread acquires the lock on an object, no other thread can enter any of the synchronized methods in that class for that object.
• If a class has both synchronized and non-synchronized methods, multiple threads can still access the class’s non-synchronized methods! If you have methods that don’t access the data you’re trying to protect, then you don’t need to synchronize them. Synchronization can cause a hit in some cases, so you should be careful not to overuse it.
• If a thread goes to sleep, it holds any locks it has—it doesn’t release them.
• A thread can acquire more than one lock. For example, a thread can enter a synchronized method, thus acquiring a lock, and then immediately invoke a synchronized method on a different object, thus acquiring that lock as well. As the methods complete, locks are released again. Also, if a thread acquires a lock and then attempts to call a synchronized method on that same object, no problem. The JVM knows that this thread already has the lock for this object, so the thread is free to call other synchronized methods on the same object, using the lock the thread already has.
• You can synchronize a block of code rather than a method.
Because synchronization does hurt concurrency, you don’t want to synchronize any more code than is necessary to protect your data. So if the scope of a method is more than needed, you can reduce the scope of the synchronized part to something less than a full method to just a block.

We call this, strangely, a synchronized block, and it looks like this:
class TestSyncdBlocks {
public void doSomething() {
System.out.println("not synchronized");
synchronized(this) {
System.out.println("synchronized");
}
}
}

When a thread is executing code from within a synchronized block, including any method code invoked from that synchronized block, the code is said to be executing in a synchronized context.

When you synchronize a method, the object used to invoke the method is the object whose lock must be acquired. But when you synchronize a block of code, you specify which object’s lock you want to use as the lock, so you could, for example, use some third-party object as the lock for this piece of code. That gives you the ability to have more than one lock for code synchronization within a single object.

Or you can synchronize on the current instance (this) as in the code above. Since that’s the same instance that synchronized methods lock on, it means that you could always replace a synchronized method with a non-synchronized method containing a synchronized block. In other words, this:

public synchronized void doSomething() {
System.out.println("synchronized");
}
is equivalent to this:
public void doSomething() {
synchronized(this) {
System.out.println("synchronized");
}
}

These methods both have the exact same effect, in practical terms. The compiled bytecodes may not be exactly the same for the two methods. The first form is shorter and more familiar to most people, but the second can be more flexible.

Static Methods and Synchronization

static methods can be synchronized. There is only one copy of the static data you’re trying to protect, so you only need one lock per class to synchronize static methods, a lock for the whole class. There is such a lock; every class loaded in Java has a corresponding instance of java.lang.Class representing that class. It’s that java.lang.Class instance whose lock is used to protect the static methods of the class (if they’re synchronized). There’s nothing special you have to do to synchronize a static method:

public static synchronized int getSomething() {
return count;
}

Again, this could be replaced with code that uses a synchronized block. If the method is defined in a class called MyClass, the equivalent code is as follows:
public static int getSomething() {
synchronized(MyClass.class) {
return count;
}
}

What’s that MyClass.class that we have used for the sync’d block? That’s called a class literal. It’s a special feature in the Java language that tells the compiler: get me the instance of Class that represents the class called MyClass. You can also do this with the following code:
public static void someMethod() {
Class cl = Class.forName("MyClass");
synchronized (cl) {
// do stuff
}
}

However that’s longer, trickier, and most importantly, not on the SCJP exam. But it’s quick and easy to use a class literal—just write the name of the class, and add .class at the end. No quotation marks needed. Now you’ve got an expression for the Class object you need to synchronize on.

What If a thread cannot get the Lock?

If a thread tries to enter a synchronized method and the lock is already taken, the thread is said to be blocked on the object’s lock. Essentially, the thread goes into a kind of pool for that particular object and has to wait there until the lock is released and the thread can again become runnable/running. Just because a lock is released doesn’t mean any particular thread will get it. There might be several threads waiting for a single lock, for example, and there’s no guarantee that the thread that has waited the longest will get the lock first.
When thinking about blocking, it’s important to pay attention to which objects are being used for locking.

• Threads calling non-static synchronized methods in the same class will only block each other if they’re invoked using the same instance. That’s because they each lock on this instance, and if they’re called using two different instances, they get two locks, which do not interfere with each other.
• Threads calling static synchronized methods in the same class will always block each other—they all lock on the same Class instance.
• A static synchronized method and a non-static synchronized method will not block each other, ever. The static method locks on a Class instance while the non-static method locks on the object instance, these actions do not interfere with each other at all.
• For synchronized blocks, you have to look at exactly what object has been used for locking. Threads that synchronize on the same object will block each other. Threads that synchronize on different objects will not.
A Synopsis of Thread related methods & Lock Availability:
Methods that give up the lock:
a. wait()

Methods that hold the lock:
a. notify()
b. join()
c. sleep()
d. yield()

When to Synchronize?

Synchronization can get pretty complicated, and you may be wondering why you would want to do this at all if you can help it. But remember the earlier “race conditions” example with Teller 1 and Teller 2 making transfers from their account. When we use threads, we usually need to use some synchronization somewhere to make sure our methods don’t interrupt each other at the wrong time and mess up our data. Generally, any time more than one thread is accessing changeable data, you synchronize to protect that data, to make sure two threads aren’t changing it at the same time. You don’t need to worry about local variables—each thread gets its own copy of a local variable. Two threads executing the same method at the same time will use different copies of the local variables, and they won’t trouble each other. However, you do need to worry about static and non-static fields, if they contain data that can be changed.

For changeable data in a non-static field, you usually use a non-static method to access it. By synchronizing that method, you will ensure that any threads trying to run that method using the same instance will be prevented from simultaneous access. But a thread working with a different instance will not be affected, because it’s acquiring a lock on the other instance. That’s what we want, threads working with the same data need to go one at a time, but threads working with different data can just ignore each other and run whenever they want to.

For changeable data in a static field, you usually use a static method to access it. And again, by synchronizing the method you ensure that any two threads trying to access the data will be prevented from simultaneous access, because both threads will have to acquire locks on the Class object for the class the static method’s defined in. Once again, that’s exactly what we want.
However, what if you have a non-static method that accesses a static field? Or a static method that accesses a non-static field (using an instance)? In these cases things start to get tricky quickly, and there’s a very good chance that things will not work the way you want. If you’ve got a static method accessing a non-static field, and you synchronize the method, you acquire a lock on the Class object. But what if there’s another method that also accesses the non-static field, this time using a non-static method? It probably synchronizes on the current instance instead. Remember that a static synchronized method and a non-static synchronized method will not block each other and they can run at the same time. Similarly, if you access a static field using a non-static method, two threads might invoke that method using two different this instances. Which means they won’t block each other, because they use different locks. Which means two threads are simultaneously accessing the same static field, which is exactly the sort of thing we’re trying to prevent.

It gets very confusing trying to imagine all the weird things that can happen here. To keep things simple: in order to make a class thread-safe, methods that access changeable fields need to be synchronized.

Access to static fields should be done from static synchronized methods. Access to non-static fields should be done from non- static synchronized methods. For example:

public class ConfuseMe {
private static int staticField;
private int nonstaticField;
public static synchronized int getStaticField() {
return staticField;
}
public static synchronized void setStaticField(int staticField) {
ConfuseMe.staticField = staticField;
}
public synchronized int getNonstaticField() {
return nonstaticField;
}
public synchronized void setNonstaticField(int nonstaticField) {
this.nonstaticField = nonstaticField;
}
}

What if you need to access both static and non-static fields in a method? Well, there are ways to do that, but it’s beyond what you need for the exam. So, for now, your are off the hook and don't need to bother much about this complicated thing that's going to make our lives harder than it already is…

Thread Safe Classes

When a class has been carefully synchronized to protect its data, we say the class is “thread-safe.” Many classes in the Java APIs already use synchronization internally in order to make the class “thread-safe.” For example, StringBuffer and StringBuilder are nearly identical classes, except that all the methods in StringBuffer are synchronized when necessary, while those in StringBuilder are not. Generally, this makes StringBuffer safe to use in a multithreaded environment, while StringBuilder is not. However, even when a class is “thread-safe,” it is often dangerous to rely on these classes to provide the thread protection you need. You still need to think carefully about how you use these classes, As an example, consider the following class.

import java.util.*;
public class ThreadSafeClass {
private List names = Collections.synchronizedList(new LinkedList());
public void addName(String name) {
names.addName(name);
}
public String removeName() {
if (names.size() > 0)
return (String) names.remove(0);
else
return null;
}
}

The method Collections.synchronizedList() returns a List whose methods are all synchronized and “thread-safe” according to the java API documentation. The question is, can the ThreadSafeClass class be used safely from multiple threads? It’s tempting to think that yes, since the data in names is in a synchronized collection, the ThreadSafeClass class is “safe” too. However that’s not the case—the removeName() may sometimes throw a NoSuchElementException. What’s the problem? Doesn’t it correctly check the size() of names before removing anything, to make sure there’s something there? How could this code fail? Let’s try to use ThreadSafeClass like this:

public static void main(String[] args) {
final ThreadSafeClass nl = new ThreadSafeClass();
nl.addName("Rocky");
class NameDropper extends Thread {
public void run() {
String name = nl.removeName();
System.out.println(name);
}
}
Thread t1 = new NameDropper();
Thread t2 = new NameDropper();
t1.start();
t2.start();
}

What might happen here is that one of the threads will remove the one name and print it, then the other will try to remove a name and get null. If we think just about the calls to names.size() and names.get(0), they occur in this order:

Thread t1 executes names.size(), which returns 1.
Thread t1 executes names.remove(0), which returns Rocky.
Thread t2 executes names.size(), which returns 0.
Thread t2 does not call remove(0).
The output here is
Rocky
null

However, if we run the program again something different might happen:

Thread t1 executes names.size(), which returns 1.
Thread t2 executes names.size(), which returns 1.
Thread t1 executes names.remove(0), which returns Rocky.
Thread t2 executes names.remove(0), which throws an exception because the list is now empty.

The thing to realize here is that in a “thread-safe” class like the one returned by synchronizedList(), each individual method is synchronized. So names.size() is synchronized, and names.remove(0) is synchronized. But nothing prevents another thread from doing something else to the list in between those two calls. And that’s when unexpected things can happen.
There’s a solution here: don’t rely on Collections.synchronizedList(). Instead, synchronize the code yourself:

import java.util.*;
public class ThreadSafeClass {
private List names = new LinkedList();
public synchronized void addName(String name) {
names.addName(name);
}
public synchronized String removeName() {
if (names.size() > 0)
return (String) names.remove(0);
else
return null;
}
}

Now the entire removeName() method is synchronized, and once one thread starts it and calls names.size(), there’s no way the other thread can cut in and steal the last name. The other thread will just have to wait until the first thread completes the removeName() method.
The moral of the story is (Like in the Value Education class in School) that just because a class is described as “thread-safe” doesn’t mean it is always thread-safe. If individual methods are synchronized, that may not be enough, you may be better off putting in synchronization logic yourself. Once you do that, the original synchronization may well become redundant.

I know that we never paid attention to the Value Education class in school, but my friend, here the moral is very important and you need to pay attention in order to pass the exam. So, do me a favor, go back to the paragraph above and read it once before you move ahead to the next topic…


Deadlocks

Perhaps the scariest thing that can happen to a Java program is deadlock. Deadlock occurs when two threads are blocked, with each waiting for the one another’s lock. Neither can run until the other gives up its lock, so they’ll sit there forever.

This can happen, for example, when thread A hits synchronized code, acquires a lock B, and then enters another method that’s also synchronized. But thread A can’t get the lock to enter this synchronized code block C because another thread D has the lock already. So thread A goes off to the “waiting for the C lock” pool, hoping that thread D will finish up its work and release the lock. But thread A will wait forever, because while thread D picked up lock C, it then entered a method synchronized on lock B. Obviously, thread D can’t get the lock B because thread A has it. And thread A won’t release it until thread D releases lock C. But thread D won’t release lock C until after it can get lock B and continue. And there they are – Stubbornly waiting for the other person to give up the lock. The following example demonstrates deadlock:

1. public class DeadlockExample {
2. private static class Car {
3. public int value;
4. }
5. private Car CarA = new Car();
6. private Car CarB = new Car();
7. public int read() {
8. synchronized(CarA) { // 1
9. synchronized(CarB) {
10. return CarB.value + CarA.value;
11. }
12. }
13. }
14.
15. public void write(int a, int b) {
16. synchronized(CarB) { // 2
17. synchronized(CarA) {
18. CarA.value = a;
19. CarB.value = b;
20. }
21. }
22. }
23. }

The lines marked with //1 and //2 are the places where we might end up with a deadlock.
Assume that read() is started by one thread and write() is started by another. If there are two different threads that may read and write independently, there is a risk of deadlock at line 8 or 16. The reader thread will have CarA, the writer thread will have CarB, and both will get stuck waiting for the other.

Code like this almost never results in deadlock because the CPU has to switch from the reader thread to the writer thread at a particular point in the code, and the chances of deadlock occurring are very small. The application may work fine most of the time.

The preceding simple example is easy to fix; just swap the order of locking for either the reader or the writer at lines 16 and 17 (or lines 8 and 9). More complex deadlock situations can take a long time to figure out and even longer to solve.

Regardless of how little chance there is for your code to deadlock, the bottom line is, if you get a deadlock, you’re dead. There are design approaches that can help avoid deadlock, including strategies for always acquiring locks in a particular order.

But that’s something you don't need for the exam.

Exam Tip:
Deadlocks are almost like stubborn fighting couples. Both parties are upset with each other and are silent and not willing to talk to one another. Unless one party speaks up and apologizes the other is going to stay silent. Fortunately we humans have emotions and most often one party apologizes and then the couples are happily married again. Unfortunately threads arent human and don't have any emotions. If one waits for the other to speak up, it waits and waits and waits. So, a smart programmer will take all possible steps to ensure that doesn't happen in his code, which I am sure you will!!!


Previous Chapter: Chapter 59 - Thread Prioritoes, yield and join methods

Next Chapter: Chapter 61 - Thread Interactions
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers