Showing posts with label Software engineering. Show all posts
Showing posts with label Software engineering. Show all posts

Jan 7, 2015

UML basics: The class diagram

The basics

The purpose of the class diagram is to show the types being modeled within the system. In most UML models these types include:
  • a class
  • an interface
  • a data type
  • a component.
UML uses a special name for these types: "classifiers." Generally, you can think of a classifier as a class, but technically a classifier is a more general term that refers to the other three types above as well.

Class name

The UML representation of a class is a rectangle containing three compartments stacked vertically, as shown in Figure 1. The top compartment shows the class's name. The middle compartment lists the class's attributes. The bottom compartment lists the class's operations. When drawing a class element on a class diagram, you must use the top compartment, and the bottom two compartments are optional. (The bottom two would be unnecessary on a diagram depicting a higher level of detail in which the purpose is to show only the relationship between the classifiers.) Figure 1 shows an airline flight modeled as a UML class. As we can see, the name is Flight, and in the middle compartment we see that the Flight class has three attributes: flightNumber, departureTime, and flightDuration. In the bottom compartment we see that the Flight class has two operations: delayFlight and getArrivalTime.
Figure 1: Class diagram for the class Flight
Class diagram for the class Flight

Class attribute list

The attribute section of a class (the middle compartment) lists each of the class's attributes on a separate line. The attribute section is optional, but when used it contains each attribute of the class displayed in a list format. The line uses the following format:
name : attribute type
flightNumber : Integer
Continuing with our Flight class example, we can describe the class's attributes with the attribute type information, as shown in Table 1.
Table 1: The Flight class's attribute names with their associated types
Attribute NameAttribute Type
flightNumberInteger
departureTimeDate
flightDurationMinutes
In business class diagrams, the attribute types usually correspond to units that make sense to the likely readers of the diagram (i.e., minutes, dollars, etc.). However, a class diagram that will be used to generate code needs classes whose attribute types are limited to the types provided by the programming language, or types included in the model that will also be implemented in the system.
Sometimes it is useful to show on a class diagram that a particular attribute has a default value. (For example, in a banking account application a new bank account would start off with a zero balance.) The UML specification allows for the identification of default values in the attribute list section by using the following notation:
name : attribute type = default value
For example:
balance : Dollars = 0
Showing a default value for attributes is optional; Figure 2 shows a Bank Account class with an attribute called balance, which has a default value of 0.
Figure 2: A Bank Account class diagram showing the balance attribute's value defaulted to zero dollars
A Bank Account class diagram showing the balance attribute's value defaulted to zero dollars

Class operations list

The class's operations are documented in the third (lowest) compartment of the class diagram's rectangle, which again is optional. Like the attributes, the operations of a class are displayed in a list format, with each operation on its own line. Operations are documented using the following notation:
name(parameter list) : type of value returned
The Flight class's operations are mapped in Table 2 below.
Table 2: Flight class's operations mapped from Figure 3
Operation Name Parameters ReturnValue Type
delayFlight
NameType
numberOfMinutes Minutes
N/A
getArrivalTime N/A Date
Figure 3 shows that the delayFlight operation has one input parameter — numberOfMinutes — of the type Minutes. However, the delayFlight operation does not have a return value. [Note: The delayFlight does not have a return value because I made a design decision not to have one. One could argue that the delay operation should return the new arrival time, and if this were the case, the operation signature would appear as delayFlight(numberOfMinutes : Minutes) : Date.] When an operation has parameters, they are put inside the operation's parentheses; each parameter uses the format "parameter name : parameter type".
Figure 3: The Flight class operations parameters include the optional "in" marking
The Flight class operations parameters include the optional 'in' marking
When documenting an operation's parameters, you may use an optional indicator to show whether or not the parameter is input to, or output from, the operation. This optional indicator appears as an "in" or "out" as shown in the operations compartment in Figure 3. Typically, these indicators are unnecessary unless an older programming language such as Fortran will be used, in which case this information can be helpful. However, in C++ and Java, all parameters are "in" parameters and since "in" is the parameter's default type according to the UML specification, most people will leave out the input/output indicators.

Inheritance

A very important concept in object-oriented design, inheritance, refers to the ability of one class (child class) to inherit the identical functionality of another class (super class), and then add new functionality of its own. (In a very non-technical sense, imagine that I inherited my mother's general musical abilities, but in my family I'm the only one who plays electric guitar.) To model inheritance on a class diagram, a solid line is drawn from the child class (the class inheriting the behavior) with a closed, unfilled arrowhead (or triangle) pointing to the super class. Consider types of bank accounts: Figure 4 shows how both CheckingAccount and SavingsAccount classes inherit from the BankAccount class.
Figure 4: Inheritance is indicated by a solid line with a closed, unfilled arrowhead pointing at the super class
Inheritance indicated by a solid line with a closed, unfilled arrowhead pointing at the super class
In Figure 4, the inheritance relationship is drawn with separate lines for each subclass, which is the method used in IBM Rational Rose and IBM Rational XDE. However, there is an alternative way to draw inheritance called tree notation. You can use tree notation when there are two or more child classes, as in Figure 4, except that the inheritance lines merge together like a tree branch. Figure 5 is a redrawing of the same inheritance shown in Figure 4, but this time using tree notation.
Figure 5: An example of inheritance using tree notation
Example of inheritance using tree notation

Abstract classes and operations

The observant reader will notice that the diagrams in Figures 4 and 5 use italicized text for the BankAccount class name and withdrawal operation. This indicates that the BankAccount class is an abstract class and the withdrawal method is an abstract operation. In other words, the BankAccount class provides the abstract operation signature of withdrawal and the two child classes of CheckingAccount and SavingsAccount each implement their own version of that operation.
However, super classes (parent classes) do not have to be abstract classes. It is normal for a standard class to be a super class.

Associations

When you model a system, certain objects will be related to each other, and these relationships themselves need to be modeled for clarity. There are five types of associations. I will discuss two of them — bi-directional and uni-directional associations — in this section, and I will discuss the remaining three association types in the Beyond the basics section. Please note that a detailed discussion of when to use each type of association is beyond the scope of this article. Instead, I will focus on the purpose of each association type and show how the association is drawn on a class diagram.

Bi-directional (standard) association

An association is a linkage between two classes. Associations are always assumed to be bi-directional; this means that both classes are aware of each other and their relationship, unless you qualify the association as some other type. Going back to our Flight example, Figure 6 shows a standard kind of association between the Flight class and the Plane class.
Figure 6: An example of a bi-directional association between a Flight class and a Plane class
An example of a bi-directional association between a Flight class and a Plane class
A bi-directional association is indicated by a solid line between the two classes. At either end of the line, you place a role name and a multiplicity value. Figure 6 shows that the Flight is associated with a specific Plane, and the Flight class knows about this association. The Plane takes on the role of "assignedPlane" in this association because the role name next to the Plane class says so. The multiplicity value next to the Plane class of 0..1 means that when an instance of a Flight exists, it can either have one instance of a Plane associated with it or no Planes associated with it (i.e., maybe a plane has not yet been assigned). Figure 6 also shows that a Plane knows about its association with the Flight class. In this association, the Flight takes on the role of "assignedFlights"; the diagram in Figure 6 tells us that the Plane instance can be associated either with no flights (e.g., it's a brand new plane) or with up to an infinite number of flights (e.g., the plane has been in commission for the last five years).
For those wondering what the potential multiplicity values are for the ends of associations, Table 3 below lists some example multiplicity values along with their meanings.
Table 3: Multiplicity values and their indicators
Potential Multiplicity Values
IndicatorMeaning
0..1 Zero or one
1One only
0..*Zero or more
* Zero or more
1..*One or more
3Three only
0..5Zero to Five
5..15 Five to Fifteen

Uni-directional association

In a uni-directional association, two classes are related, but only one class knows that the relationship exists. Figure 7 shows an example of an overdrawn accounts report with a uni-directional association.
Figure 7: An example of a uni-directional association: The OverdrawnAccountsReport class knows about the BankAccount class, but the BankAccount class does not know about the association
An example of a uni-directional association
A uni-directional association is drawn as a solid line with an open arrowhead (not the closed arrowhead, or triangle, used to indicate inheritance) pointing to the known class. Like standard associations, the uni-directional association includes a role name and a multiplicity value, but unlike the standard bi-directional association, the uni-directional association only contains the role name and multiplicity value for the known class. In our example in Figure 7, the OverdrawnAccountsReport knows about the BankAccount class, and the BankAccount class plays the role of "overdrawnAccounts." However, unlike a standard association, the BankAccount class has no idea that it is associated with the OverdrawnAccountsReport. [Note: It may seem strange that the BankAccount class does not know about the OverdrawnAccountsReport class. This modeling allows report classes to know about the business class they report, but the business classes do not know they are being reported on. This loosens the coupling of the objects and therefore makes the system more adaptive to changes.]

Packages

Inevitably, if you are modeling a large system or a large area of a business, there will be many different classifiers in your model. Managing all the classes can be a daunting task; therefore, UML provides an organizing element called a package. Packages enable modelers to organize the model's classifiers into namespaces, which is sort of like folders in a filing system. Dividing a system into multiple packages makes the system easier to understand, especially if each package represents a specific part of the system. [Note: Packages are great for organizing your model's classes, but it's important to remember that your class diagrams are supposed to easily communicate information about the system being modeled. In cases where your packages have lots of classes, it is better to use multiple topic-specific class diagrams instead of just producing one large class diagram.]
There are two ways of drawing packages on diagrams. There is no rule for determining which notation to use, except to use your personal judgement regarding which is easiest to read for the class diagram you are drawing. Both ways begin with a large rectangle with a smaller rectangle (tab) above its upper left corner, as seen in Figure 8. But the modeler must decide how the package's membership is to be shown, as follows:
  • If the modeler decides to show the package's members within the large rectangle, then all those members need to be placed within the rectangle. [Note: It's important to understand that when I say "all those members," I mean only the classes that the current diagram is going to show. A diagram showing a package with contents does not need to show all its contents; it can show a subset of the contained elements according to some criterion, which is not necessarily all the package's classifiers.] Also the package's name needs to be placed in the package's smaller rectangle (as show n in Figure 8).
  • If the modeler decides to show the package's members outside the large rectangle then all the members that will be shown on the diagram need to be placed outside the rectangle. To show what classifiers belong to the package, a line is drawn from each classifier to a circle that has a plus sign inside the circle attached to the package (Figure 9).
Figure 8: An example package element that shows its members inside the package's rectangle boundaries
An example package element that shows its members inside the package's rectangle boundaries
Figure 9: An example package element showing its membership via connected lines
Figure 9 caption describes image

Importance of understanding the basics

It is more important than ever in UML 2 to understand the basics of the class diagram. This is because the class diagram provides the basic building blocks for all other structure diagrams, such as the component or object diagrams (just to name a few).

Beyond the basics

At this point, I have covered the basics of the class diagram, but do not stop reading yet! In the following sections, I will address more important aspects of the class diagram that you can put to good use. These include interfaces, the three remaining types of associations, visibility, and other additions in the UML 2 specification.

Interfaces

Earlier in this article, I suggested that you think of classifiers simply as classes. In fact, a classifier is a more general concept, which includes data types and interfaces.
A complete discussion of when and how to use data types and interfaces effectively in a system's structure diagrams is beyond the scope of this article. So why do I mention data types and interfaces here? There are times when you might want to model these classifier types on a structure diagram, and it is important to use the proper notation in doing so, or at least be aware of these classifier types. Drawing these classifiers incorrectly will likely confuse readers of your structure diagram, and the ensuing system will probably not meet requirements.
A class and an interface differ: A class can have an actual instance of its type, whereas an interface must have at least one class to implement it. In UML 2, an interface is considered to be a specialization of a class modeling element. Therefore, an interface is drawn just like a class, but the top compartment of the rectangle also has the text "«interface»", as shown in Figure 10. [Note: When drawing a class diagram it is completely within UML specification to put «class» in the top compartment of the rectangle, as you would with «interface»; however, the UML specification says that placing the "class" text in this compartment is optional, and it should be assumed if «class» is not displayed.]
Figure 10: Example of a class diagram in which the Professor and Student classes implement the Person interface
Example of a class diagram in which the Professor and Student classes implement the Person interface
In the diagram shown in Figure 10, both the Professor and Student classes implement the Person interface and do not inherit from it. We know this for two reasons: 1) The Person object is defined as an interface — it has the "«interface»" text in the object's name area, and we see that the Professor and Student objects are class objects because they are labeled according to the rules for drawing a class object (there is no additional classification text in their name area). 2) We know inheritance is not being shown here, because the line with the arrow is dotted and not solid. As shown in Figure 10, a dotted line with a closed, unfilled arrow means realization (or implementation); as we saw in Figure 4, a solid arrow line with a closed, unfilled arrow means inheritance.

More associations

Above, I discussed bi-directional and uni-directional associations. Now I will address the three remaining types of associations.

Association class

In modeling an association, there are times when you need to include another class because it includes valuable information about the relationship. For this you would use an association class that you tie to the primary association. An association class is represented like a normal class. The difference is that the association line between the primary classes intersects a dotted line connected to the association class. Figure 11 shows an association class for our airline industry example.
Figure 11: Adding the association class MileageCredit
Adding the association class MileageCredit
In the class diagram shown in Figure 11, the association between the Flight class and the FrequentFlyer class results in an association class called MileageCredit. This means that when an instance of a Flight class is associated with an instance of a FrequentFlyer class, there will also be an instance of a MileageCredit class.

Aggregation

Aggregation is a special type of association used to model a "whole to its parts" relationship. In basic aggregation relationships, the lifecycle of a part class is independent from the whole class's lifecycle.
For example, we can think of Car as a whole entity and Car Wheel as part of the overall Car. The wheel can be created weeks ahead of time, and it can sit in a warehouse before being placed on a car during assembly. In this example, the Wheel class's instance clearly lives independently of the Car class's instance. However, there are times when the part class's lifecycle is not independent from that of the whole class — this is called composition aggregation. Consider, for example, the relationship of a company to its departments. Both Company and Departments are modeled as classes, and a department cannot exist before a company exists. Here the Department class's instance is dependent upon the existence of the Company class's instance.
Let's explore basic aggregation and composition aggregation further.
Basic aggregation
An association with an aggregation relationship indicates that one class is a part of another class. In an aggregation relationship, the child class instance can outlive its parent class. To represent an aggregation relationship, you draw a solid line from the parent class to the part class, and draw an unfilled diamond shape on the parent class's association end. Figure 12 shows an example of an aggregation relationship between a Car and a Wheel.
Figure 12: Example of an aggregation association
Example of an aggregation association
Composition aggregation
The composition aggregation relationship is just another form of the aggregation relationship, but the child class's instance lifecycle is dependent on the parent class's instance lifecycle. In Figure 13, which shows a composition relationship between a Company class and a Department class, notice that the composition relationship is drawn like the aggregation relationship, but this time the diamond shape is filled.
Figure 13: Example of a composition relationship
Example of a composition relationship
In the relationship modeled in Figure 13, a Company class instance will always have at least one Department class instance. Because the relationship is a composition relationship, when the Company instance is removed/destroyed, the Department instance is automatically removed/destroyed as well. Another important feature of composition aggregation is that the part class can only be related to one instance of the parent class (e.g. the Company class in our example).

Reflexive associations

We have now discussed all the association types. As you may have noticed, all our examples have shown a relationship between two different classes. However, a class can also be associated with itself, using a reflexive association. This may not make sense at first, but remember that classes are abstractions. Figure 14 shows how an Employee class could be related to itself through the manager/manages role. When a class is associated to itself, this does not mean that a class's instance is related to itself, but that an instance of the class is related to another instance of the class.
Figure 14: Example of a reflexive association relationship
Example of a reflexive association relationship
The relationship drawn in Figure 14 means that an instance of Employee can be the manager of another Employee instance. However, because the relationship role of "manages" has a multiplicity of 0..*; an Employee might not have any other Employees to manage.

Visibility

In object-oriented design, there is a notation of visibility for attributes and operations. UML identifies four types of visibility: public, protected, private, and package.
The UML specification does not require attributes and operations visibility to be displayed on the class diagram, but it does require that it be defined for each attribute or operation. To display visibility on the class diagram, you place the visibility mark in front of the attribute's or operation's name. Though UML specifies four visibility types, an actual programming language may add additional visibilities, or it may not support the UML-defined visibilities. Table 4 displays the different marks for the UML-supported visibility types.
Table 4: Marks for UML-supported visibility types
MarkVisibility type
+Public
# Protected
- Private
~Package
Now, let's look at a class that shows the visibility types indicated for its attributes and operations. In Figure 15, all the attributes and operations are public, with the exception of the updateBalance operation. The updateBalance operation is protected.
Figure 15: A BankAccount class that shows the visibility of its attributes and operations
A BankAccount class showing visibility of attributes and operations

UML 2 additions

Now that we have covered the basics and the advanced topics, we will cover some of the new notations added to the class diagram from UML 1.x.

Instances

When modeling a system's structure it is sometimes useful to show example instances of the classes. To model this, UML 2 provides the instance specification element, which shows interesting information using example (or real) instances in the system.
The notation of an instance is the same as a class, but instead of the top compartment merely having the class's name, the name is an underlined concatenation of:
Instance Name : Class Name
For example:
Donald : Person
Because the purpose of showing instances is to show interesting or relevant information, it is not necessary to include in your model the entire instance's attributes and operations. Instead it is completely appropriate to show only the attributes and their values that are interesting as depicted in Figure 16.
Figure 16: An example instance of a Plane class (only the interesting attribute values are shown)
An example instance of a Plane class
However, merely showing some instances without their relationship is not very useful; therefore, UML 2 allows for the modeling of the relationships/associations at the instance level as well. The rules for drawing associations are the same as for normal class relationships, although there is one additional requirement when modeling the associations. The additional restriction is that association relationships must match the class diagram's relationships and therefore the association's role names must also match the class diagram. An example of this is shown in Figure 17. In this example the instances are example instances of the class diagram found in Figure 6.
Figure 17: An example of Figure 6 using instances instead of classes
An example of Figure 6 using instances instead of classes
Figure 17 has two instances of the Flight class because the class diagram indicated that the relationship between the Plane class and the Flight class is zero-to-many. Therefore, our example shows the two Flight instances that the NX0337 Plane instance is related to.

Roles

Modeling the instances of classes is sometimes more detailed than one might wish. Sometimes, you may simply want to model a class's relationship at a more generic level. In such cases, you should use the role notation. The role notation is very similar to the instances notation. To model a class's role, you draw a box and place the class's role name and class name inside as with the instances notation, but in this case you do not underline the words. Figure 18 shows an example of the roles played by the Employee class described by the diagram at Figure 14. In Figure 18, we can tell, even though the Employee class is related to itself, that the relationship is really between an Employee playing the role of manager and an Employee playing the role of team member.
Figure 18: A class diagram showing the class in Figure 14 in its different roles
A class diagram showing the class in Figure 14 in its different roles
Note that you cannot model a class's role on a plain class diagram, even though Figure 18 makes it appear that you can. In order to use the role notation you will need to use the Internal Structure notation, discussed next.

Internal Structures

One of the more useful features of UML 2 structure diagrams is the new internal structure notation. It allows you to show how a class or another classifier is internally composed. This was not possible in UML 1.x, because the notation set limited you to showing only the aggregation relationships that a class had. Now, in UML 2, the internal structure notation lets you more clearly show how that class's parts relate to each other.
Let's look at an example. In Figure 18 we have a class diagram showing how a Plane class is composed of four engines and two control software objects. What is missing from this diagram is any information about how airplane parts are assembled. From the diagram in Figure 18, you cannot tell if the control software objects control two engines each, or if one control software object controls three engines and the other controls one engine.
Figure 19: A class diagram that only shows relationships between the objects
A class diagram showing relationship between objects
Drawing a class's internal structure will improve this situation. You start by drawing a box with two compartments. The top compartment contains the class name, and the lower compartment contains the class's internal structure, showing the parent class's part classes in their respective roles, as well as how each particular class relates to others in that role. Figure 19 shows the internal structure of Plane class; notice how the internal structure clears up the confusion.
Figure 20: An example internal structure of a Plane class
An example internal structure of a Plane class
In Figure 20 the Plane has two ControlSoftware objects and each one controls two engines. The ControlSoftware on the left side of the diagram (control1) controls engines 1 and 2. The ControlSoftware on the right side of the diagram (control2) controls engines 3 and 4.

(Source: Wikipedia)

Sep 7, 2014

Java Thread Pool tutorial

A thread pool manages the pool of worker threads, it contains a queue that keeps tasks waiting to get executed.
A thread pool manages the collection of Runnable threads and worker threads execute Runnable from the queue.
java.util.concurrent.Executors provide implementation of java.util.concurrent.Executor interface to create the thread pool in java. Let’s write a simple program to explain it’s working.
First we need to have a Runnable class.

WorkerThread.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.journaldev.threadpool;
 
public class WorkerThread implements Runnable {
     
    private String command;
     
    public WorkerThread(String s){
        this.command=s;
    }
 
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" Start. Command = "+command);
        processCommand();
        System.out.println(Thread.currentThread().getName()+" End.");
    }
 
    private void processCommand() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
 
    @Override
    public String toString(){
        return this.command;
    }
}
Here is the test program where we are creating fixed thread pool from Executors framework.
SimpleThreadPool.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.journaldev.threadpool;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class SimpleThreadPool {
 
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            Runnable worker = new WorkerThread("" + i);
            executor.execute(worker);
          }
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }
 
}
In above program, we are creating fixed size thread pool of 5 worker threads. Then we are submitting 10 jobs to this pool, since the pool size is 5, it will start working on 5 jobs and other jobs will be in wait state, as soon as one of the job is finished, another job from the wait queue will be picked up by worker thread and get’s executed.
Here is the output of the above program.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
pool-1-thread-2 Start. Command = 1
pool-1-thread-4 Start. Command = 3
pool-1-thread-1 Start. Command = 0
pool-1-thread-3 Start. Command = 2
pool-1-thread-5 Start. Command = 4
pool-1-thread-4 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
pool-1-thread-3 End.
pool-1-thread-3 Start. Command = 8
pool-1-thread-2 End.
pool-1-thread-2 Start. Command = 9
pool-1-thread-1 Start. Command = 7
pool-1-thread-5 Start. Command = 6
pool-1-thread-4 Start. Command = 5
pool-1-thread-2 End.
pool-1-thread-4 End.
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-1 End.
Finished all threads
The output confirms that there are five threads in the pool named from “pool-1-thread-1″ to “pool-1-thread-5″ and they are responsible to execute the submitted tasks to the pool.
Executors class provide simple implementation of ExecutorService using ThreadPoolExecutor but ThreadPoolExecutor provides much more feature than that. We can specify the number of threads that will be alive when we create ThreadPoolExecutor instance and we can limit the size of thread pool and create our own RejectedExecutionHandler implementation to handle the jobs that can’t fit in the worker queue.
Here is our custom implementation of RejectedExecutionHandler interface.
RejectedExecutionHandlerImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.journaldev.threadpool;
 
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
 
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {
 
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        System.out.println(r.toString() + " is rejected");
    }
 
}
ThreadPoolExecutor provides several methods using which we can find out the current state of executor, pool size, active thread count and task count. So I have a monitor thread that will print the executor information at certain time interval.

MyMonitorThread.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.journaldev.threadpool;
 
import java.util.concurrent.ThreadPoolExecutor;
 
public class MyMonitorThread implements Runnable
{
    private ThreadPoolExecutor executor;
     
    private int seconds;
     
    private boolean run=true;
 
    public MyMonitorThread(ThreadPoolExecutor executor, int delay)
    {
        this.executor = executor;
        this.seconds=delay;
    }
     
    public void shutdown(){
        this.run=false;
    }
 
    @Override
    public void run()
    {
        while(run){
                System.out.println(
                    String.format("[monitor] [%d/%d] Active: %d, Completed: %d, Task: %d, isShutdown: %s, isTerminated: %s",
                        this.executor.getPoolSize(),
                        this.executor.getCorePoolSize(),
                        this.executor.getActiveCount(),
                        this.executor.getCompletedTaskCount(),
                        this.executor.getTaskCount(),
                        this.executor.isShutdown(),
                        this.executor.isTerminated()));
                try {
                    Thread.sleep(seconds*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
             
    }
}
Here is the thread pool implementation example using ThreadPoolExecutor.
WorkerPool.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.journaldev.threadpool;
 
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
public class WorkerPool {
 
    public static void main(String args[]) throws InterruptedException{
        //RejectedExecutionHandler implementation
        RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();
        //Get the ThreadFactory implementation to use
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        //creating the ThreadPoolExecutor
        ThreadPoolExecutor executorPool = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2), threadFactory, rejectionHandler);
        //start the monitoring thread
        MyMonitorThread monitor = new MyMonitorThread(executorPool, 3);
        Thread monitorThread = new Thread(monitor);
        monitorThread.start();
        //submit work to the thread pool
        for(int i=0; i<10; i++){
            executorPool.execute(new WorkerThread("cmd"+i));
        }
         
        Thread.sleep(30000);
        //shut down the pool
        executorPool.shutdown();
        //shut down the monitor thread
        Thread.sleep(5000);
        monitor.shutdown();
         
    }
}
Notice that while initializing the ThreadPoolExecutor, we are keeping initial pool size as 2, maximum pool size to 4 and work queue size as 2. So if there are 4 running tasks and more tasks are submitted, the work queue will hold only 2 of them and rest of them will be handled by RejectedExecutionHandlerImpl.
Here is the output of above program that confirms above statement.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
pool-1-thread-1 Start. Command = cmd0
pool-1-thread-4 Start. Command = cmd5
cmd6 is rejected
pool-1-thread-3 Start. Command = cmd4
pool-1-thread-2 Start. Command = cmd1
cmd7 is rejected
cmd8 is rejected
cmd9 is rejected
[monitor] [0/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false
[monitor] [4/2] Active: 4, Completed: 0, Task: 6, isShutdown: false, isTerminated: false
pool-1-thread-4 End.
pool-1-thread-1 End.
pool-1-thread-2 End.
pool-1-thread-3 End.
pool-1-thread-1 Start. Command = cmd3
pool-1-thread-4 Start. Command = cmd2
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false
[monitor] [4/2] Active: 2, Completed: 4, Task: 6, isShutdown: false, isTerminated: false
pool-1-thread-1 End.
pool-1-thread-4 End.
[monitor] [4/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [2/2] Active: 0, Completed: 6, Task: 6, isShutdown: false, isTerminated: false
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true
[monitor] [0/2] Active: 0, Completed: 6, Task: 6, isShutdown: true, isTerminated: true
Notice the change in active, completed and total completed task count of the executor. We can invoke shutdown() method to finish execution of all the submitted tasks and terminate the thread pool.
If you want to schedule a task to run with delay or periodically then you can use ScheduledThreadPoolExecutor class. Read more about them at Java Schedule Thread Pool Executor.


Source: Internet

May 9, 2014

Java exception handling best practices

This post is another addition in best practices series available in this blog. In this post, I am covering some well-known and some little known practices which you must consider while handling exceptions in your next java programming assignment. Follow this link to read more about exception handling in java.
Sections in this post

Type of exceptions
User defined custom exceptions

Best practices you must consider and follow

Never swallow the exception in catch block
Declare the specific checked exceptions that your method can throw
Do not catch the Exception class rather catch specific sub classes
Never catch Throwable class
Always correctly wrap the exceptions in custom exceptions so that stack trace is not lost
Either log the exception or throw it but never do the both
Never throw any exception from finally block
Always catch only those exceptions that you can actually handle
Don't use printStackTrace() statement or similar methods
Use finally blocks instead of catch blocks if you are not going to handle exception
Remember "Throw early catch late" principle
Always clean up after handling the exception
Throw only relevant exception from a method
Never use exceptions for flow control in your program
Validate user input to catch adverse conditions very early in request processing
Always include all information about an exception in single log message
Pass all relevant information to exceptions to make them informative as much as possible
Always terminate the thread which it is interrupted
Use template methods for repeated try-catch
Document all exceptions in your application in javadoc
Before we dive into deep concepts of exception handling best practices, lets start with one of the most important concepts which is to understand that there are three general types of throwable classes in Java: checked exceptions, unchecked exceptions, and errors.

Type of exceptions

Exception Hierarchy in java
Exception Hierarchy in java
Checked exceptions are exceptions that must be declared in the throws clause of a method. They extend Exception and are intended to be an “in your face” type of exceptions. Java wants you to handle them because they somehow are dependent on external factors outside your program. A checked exception indicates an expected problem that can occur during normal system operation. Mostly these exception happen when you try to use external systems over network or in file system. Mostly, the correct response to a checked exception should be to try again later, or to prompt the user to modify his input.
Unchecked exceptions are exceptions that do not need to be declared in a throws clause. JVM simply doesn’t force you to handle them as they are mostly generated at runtime due to programmatic errors. They extend RuntimeException. The most common example is a NullPointerException [Quite scary.. Isn't it?]. An unchecked exception probably shouldn’t be retried, and the correct action should be usually to do nothing, and let it come out of your method and through the execution stack. At a high level of execution, this type of exceptions should be logged.
Errors are serious runtime environment problems that are almost certainly not recoverable. Some examples are OutOfMemoryError, LinkageError, and StackOverflowError. They generally crash you program or part of program. Only a good logging practice will help you in determining the exact causes of errors.

User defined custom exceptions

Anytime when user feels that he wants to use its own application specific exception for some reasons, he can create a new class extending appropriate super class (mostly its Exception.java) and start using it in appropriate places. These user defined exceptions can be used in two ways:
1) Either directly throw the custom exception when something goes wrong in application
throw new DaoObjectNotFoundException("Couldn't find dao with id " + id);
2) Or wrap the original exception inside custom exception and throw it
catch (NoSuchMethodException e) {
  throw new DaoObjectNotFoundException("Couldn't find dao with id " + id, e);
}
Wrapping an exception can provide extra information to the user by adding your own message/ context information, while still preserving the stack trace and message of the original exception. It also allows you to hide the implementation details of your code, which is the most important reason to wrap exceptions.
Now lets start exploring the best practices followed for exception handling industry wise.

Best practices you must consider and follow

1) Never swallow the exception in catch block
1.catch (NoSuchMethodException e) {
2.return null;
3.}
Doing this not only return “null” instead of handling or re-throwing the exception, it totally swallows the exception, losing the cause of error forever. And when you don’t know the reason of failure, how you would prevent it in future? Never do this !!
2) Declare the specific checked exceptions that your method can throw
1.public void foo() throws Exception { //Incorrect way
2.}
Always avoid doing this as in above code sample. It simply defeats the whole purpose of having checked exception. Declare the specific checked exceptions that your method can throw. If there are just too many such checked exceptions, you should probably wrap them in your own exception and add information to in exception message. You can also consider code refactoring also if possible.
1.public void foo() throws SpecificException1, SpecificException2 { //Correct way
2.}
3) Do not catch the Exception class rather catch specific sub classes
1.try {
2.someMethod();
3.} catch (Exception e) {
4.LOGGER.error("method has failed", e);
5.}
The problem with catching Exception is that if the method you are calling later adds a new checked exception to its method signature, the developer’s intent is that you should handle the specific new exception. If your code just catches Exception (or Throwable), you’ll never know about the change and the fact that your code is now wrong and might break at any point of time in runtime.
4) Never catch Throwable class
Well, its one step more serious trouble. Because java errors are also subclasses of the Throwable. Errors are irreversible conditions that can not be handled by JVM itself. And for some JVM implementations, JVM might not actually even invoke your catch clause on an Error.
5) Always correctly wrap the exceptions in custom exceptions so that stack trace is not lost
1.catch (NoSuchMethodException e) {
2.throw new MyServiceException("Some information: " + e.getMessage());  //Incorrect way
3.}
This destroys the stack trace of the original exception, and is always wrong. The correct way of doing this is:
1.catch (NoSuchMethodException e) {
2.throw new MyServiceException("Some information: " , e);  //Correct way
3.}
6) Either log the exception or throw it but never do the both
1.catch (NoSuchMethodException e) {
2.LOGGER.error("Some information", e);
3.throw e;
4.}
As in above example code, logging and throwing will result in multiple log messages in log files, for a single problem in the code, and makes life hell for the engineer who is trying to dig through the logs.
7) Never throw any exception from finally block
1.try {
2.someMethod();  //Throws exceptionOne
3.} finally {
4.cleanUp();    //If finally also threw any exception the exceptionOne will be lost forever
5.}
This is fine, as long as cleanUp() can never throw any exception. In the above example, if someMethod() throws an exception, and in the finally block also, cleanUp() throws an exception, that second exception will come out of method and the original first exception (correct reason) will be lost forever. If the code that you call in a finally block can possibly throw an exception, make sure that you either handle it, or log it. Never let it come out of the finally block.
8) Always catch only those exceptions that you can actually handle
1.catch (NoSuchMethodException e) {
2.throw e; //Avoid this as it doesn't help anything
3.}
Well this is most important concept. Don’t catch any exception just for the sake of catching it. Catch any exception only if you want to handle it or, you want to provide additional contextual information in that exception. If you can’t handle it in catch block, then best advice is just don’t catch it only to re-throw it.
9) Don’t use printStackTrace() statement or similar methods
Never leave printStackTrace() after finishing your code. Chances are one of your fellow colleague will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it because it will not have any contextual information appended to it.
10) Use finally blocks instead of catch blocks if you are not going to handle exception
1.try {
2.someMethod();  //Method 2
3.} finally {
4.cleanUp();    //do cleanup here
5.}
This is also a good practice. If inside your method you are accessing some method 2, and method 2 throw some exception which you do not want to handle in method 1, but still want some cleanup in case exception occur, then do this cleanup in finally block. Do not use catch block.
11) Remember “Throw early catch late” principle
This is probably the most famous principle about Exception handling. It basically says that you should throw an exception as soon as you can, and catch it late as much as possible. You should wait until you have all the information to handle it properly.
This principle implicitly says that you will be more likely to throw it in the low-level methods, where you will be checking if single values are null or not appropriate. And you will be making the exception climb the stack trace for quite several levels until you reach a sufficient level of abstraction to be able to handle the problem.
12) Always clean up after handling the exception
If you are using resources like database connections or network connections, make sure you clean them up. If the API you are invoking uses only unchecked exceptions, you should still clean up resources after use, with try – finally blocks. Inside try block access the resource and inside finally close the resource. Even if any exception occur in accessing the resource, then also resource will be closed gracefully.
13) Throw only relevant exception from a method
Relevancy is important to keep application clean. A method which tries to read a file; if throws NullPointerException then it will not give any relevant information to user. Instead it will be better if such exception is wrapped inside custom exception e.g. NoSuchFileFoundException then it will be more useful for users of that method.
14) Never use exceptions for flow control in your program
We have read it many times but sometimes we keep seeing code in our project where developer tries to use exceptions for application logic. Never do that. It makes code hard to read, understand and ugly.
15) Validate user input to catch adverse conditions very early in request processing
Always validate user input in very early stage, even before it reached to actual controller. It will help you to minimize the exception handling code in your core application logic. It also helps you in making application consistent if there is some error in user input.
For example: If in user registration application, you are following below logic:
1) Validate User
2) Insert User
3) Validate address
4) Insert address
5) If problem the Rollback everything
This is very incorrect approach. It can leave you database in inconsistent state in various scenarios. Rather validate everything in first place and then take the user data in dao layer and make DB updates. Correct approach is:
1) Validate User
2) Validate address
3) Insert User
4) Insert address
5) If problem the Rollback everything
16) Always include all information about an exception in single log message
LOGGER.debug(“Using cache sector A”);
LOGGER.debug(“Using retry sector B”);
Don’t do this.
Using a multi-line log message with multiple calls to LOGGER.debug() may look fine in your test case, but when it shows up in the log file of an app server with 400 threads running in parallel, all dumping information to the same log file, your two log messages may end up spaced out 1000 lines apart in the log file, even though they occur on subsequent lines in your code.
Do it like this:
LOGGER.debug(“Using cache sector A, using retry sector B”);
17) Pass all relevant information to exceptions to make them informative as much as possible
This is also very important to make exception messages and stack traces useful and informative. What is the use of a log, if you are not able to determine anything out of it. These type of logs just exist in your code for decoration purpose.
18) Always terminate the thread which it is interrupted
1.while (true) {
2.try {
3.Thread.sleep(100000);
4.} catch (InterruptedException e) {} //Don't do this
5.doSomethingCool();
6.}
InterruptedException is a clue to your code that it should stop whatever it’s doing. Some common use cases for a thread getting interrupted are the active transaction timing out, or a thread pool getting shut down. Instead of ignoring the InterruptedException, your code should do its best to finish up what it’s doing, and finish the current thread of execution. So to correct the example above:
1.while (true) {
2.try {
3.Thread.sleep(100000);
4.} catch (InterruptedException e) {
5.break;
6.}
7.}
8.doSomethingCool();
19) Use template methods for repeated try-catch
There is no use of having a similar catch block in 100 places in your code. It increases code duplicity which does not help anything. Use template methods for such cases.
For example below code tries to close a database connection.
01.class DBUtil{
02.public static void closeConnection(Connection conn){
03.try{
04.conn.close();
05.} catch(SQLException ex){
06.throw new RuntimeException("Cannot close connection", ex);
07.}
08.}
09.}
This type of method will be used in thousands of places in your application. Don’t put whole code in every place rather define above method and use it everywhere like below:
01.public void dataAccessCode() {
02.Connection conn = null;
03.try{
04.conn = getConnection();
05.....
06.} finally{
07.DBUtil.closeConnection(conn);
08.}
09.}
20) Document all exceptions in your application in javadoc
Make it a practice to javadoc all exceptions which a piece of code may throw at runtime. Also try to include possible course of action, user should follow in case these exception occur.
That’s all i have in my mind for now. If you found anything missing or you does not relate to my view on any point, drop me a comment. I will be happy to discuss.

(Source: Internet)