Wednesday, January 25, 2012

Creating Listeners Containing a Single Method Call


Java SE 1.4 introduces a mechanism that lets you specify simple event listeners without programming inner classes. (I am one of those people who doesn't like to use inner classes much, so I take any opportunity that is available to avoid using them) For example, suppose you have a button labeled “Load” whose event handler contains a single method call:
frame.loadData();

Of course, you can always use an anonymous inner class:

loadButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.loadData();
}
});


But the EventHandler class can create such a listener automatically, with the call
EventHandler.create(ActionListener.class, frame, "loadData")

Of course, you still need to install the handler:
loadButton.addActionListener(EventHandler.create(ActionListener.class, frame, "loadData"));

If the listener calls a method with a single parameter that can be obtained from the event parameter, you can use another form of the create method. For example
EventHandler.create(ActionListener.class, frame, "loadData", "source.text")

is equivalent to


new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.loadData(((JTextField) event.getSource()).getText());
}
}



The property names source and text turn into method calls getSource and getText.

A Working Example:

Let us understand the usage of these single method calls better with a simple example.
As you might have figured out by now, Swing programs use the Metal look and feel by default (We haven’t set any look and feel till now in our Swing programs, or have we?) There are two ways to change to a different look and feel. The first way is to supply a file swing.properties in the jre/lib subdirectory of your Java installation. In that file, set the property swing.defaultlaf to the class name of the look and feel that you want. For example:
swing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel

Note that the Metal look and feel is located in the javax.swing package. The other look-and-feel packages are located in the com.sun.java package and need not be present in every Java implementation. Currently, for copyright reasons, the Windows and Macintosh look-and-feel packages are only shipped with the Windows and Macintosh versions of the Java runtime environment.
The second way is to change the look and feel dynamically. Call the static UIManager.setLookAndFeel method and give it the name of the look-and-feel class that you want. Then call the static method SwingUtilities.updateComponentTreeUI to refresh the entire set of components. You need to supply one component to that method; it will find all others. The UIManager.setLookAndFeel method may throw a number of exceptions when it can’t find the look and feel that you request, or when there is an error loading it. Worrying about those exceptions is currently out of our scope and we will deal with them later.

Here is an example showing how you can switch to the Motif look and feel in your program:


String plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
try
{
UIManager.setLookAndFeel(plaf);
SwingUtilities.updateComponentTreeUI(panel);
}
catch(Exception e) { e.printStackTrace(); }



To list down all installed look and feel implementations, call

UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();

Then you can get the name and class name for each look and feel as below:
String name = infos[i].getName();
String className = infos[i].getClassName();

Lets now look at the code for a class that will dynamically change the look and feel of our screen. Our code will identify the available look and feel based on the code snippet above and create buttons dynamically mentioning them. When we click on each of the buttons, the look and feel of the frame and the components inside it will change dynamically.

Code:


import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;

/**
* @version 1.1 02-June-2011
* @author Anand Vijayakumar
*/
public class TestLookNFeel
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
LookNFeelFrame frame = new LookNFeelFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

/**
* A frame with a button panel for changing look and feel
*/
class LookNFeelFrame extends JFrame
{
public LookNFeelFrame()
{
setTitle("Look N Feel Test");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

buttonPanel = new JPanel();

UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
for (UIManager.LookAndFeelInfo info : infos)
makeButton(info.getName(), info.getClassName());

add(buttonPanel);
}

/**
* Makes a button to change the look and feel.
*/
void makeButton(String name, final String plafName)
{
// add button to panel

JButton button = new JButton(name);
buttonPanel.add(button);

// set button action

button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
// button action: switch to the new look and feel
try
{
UIManager.setLookAndFeel(plafName);
SwingUtilities.updateComponentTreeUI(LookNFeelFrame.this);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}

private JPanel buttonPanel;

public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
}


If you run this code, you may get a different number of buttons in your computer. I got 4 in mine and the output if I click on each is as follows:


Previous: Basics of Event Handling

Monday, January 9, 2012

Chapter 13: Nested Locks


Imagine a scenario where a synchronized method is calling a non-synchronized method of the same object. In such a situation, the new method has no reason to obtain the lock because; the method calling it already owns the lock.

The reason this works is that Java does not blindly grab the lock when it enters synchronized code. If the current thread owns the lock, there is no reason to wait for the lock to be freed or even to grab the lock. Instead, the code in the synchronized section just executes. Furthermore, the system is smart enough to not free the lock if it did not initially grab it upon entering the synchronized section of code. This works because the system keeps track of the number of recursive acquisitions of the lock, finally freeing the lock upon exiting the first method (or block) that acquired the lock. This functionality is called nested locking.

Yet, it will be a good idea to synchronize methods like this. Are you tempted to ask “Why?”

If you were, think of this scenario. Let’s say another developer makes some new code changes without knowing that this code needs to have the object lock. So, if this developer makes some changes that might affect the way the thread executes or how the locks are acquired, then your code will be messed up big time. That is why I said, it would be a good idea to synchronize those methods as well.

Nested locks are also supported by the ReentrantLock class; the class that implements the Lock interface that we used in the previous chapters. If a lock request is made by the thread that currently owns the lock, the ReentrantLock object just increments an internal count of the number of nested lock requests. Calls to the unlock() method decrement the count. The lock is not freed until the lock count reaches zero. This implementation allows these locks to behave exactly like the synchronized keyword. Note, however, that this is a specific property of the ReentrantLock class and not a general property of classes that implement the Lock interface.

The ReentrantLock classlooks like below:
public class ReentrantLock implements Lock {
public int getHoldCount( );
public boolean isLocked( );
public boolean isHeldByCurrentThread( );
public int getQueueLength( );
}

The getHoldCount() method returns the number of acquisitions that the current thread has made on the lock. A return value of zero means that the current thread does not own the lock: it does not mean that the lock is free. To determine if the lock is free; not acquired by any thread; the isLocked() method may be used.

Two other methods of the ReentrantLock class are also important to this discussion. The isHeldByCurrentThread() method is used to determine if the thread is owned by the current thread, and the getQueueLength() method can be used to get an estimate of the number of threads waiting to acquire the lock. This value that is returned is only an estimate due to the race condition that exists between the time that the value is calculated and the time that the value is used after it has been returned.

Previous: Choosing a Locking Mechanism

Chapter 12: Choosing a Locking Mechanism


After reading the previous chapters on locks and synchronization, you may be wondering, how would I choose a locking mechanism for my multi-threaded code?

Well, before we answer this doubt, using synchronized methods or blocks is much easier than using the explicit locking mechanism. Using the synchronized keyword, you need not manually grab and release the lock so, the chances of any unexpected exceptions are very minimal (unless your code has a hole through which I can drive a truck, the usage of synchronized keyword does not cause exceptions by itself)

Ok, coming back to the answer, it is possible to use explicit locking for everything. It is possible to code to just use the synchronized keyword. And it is possible to use a combination of both. Avoid using the explicit locking unless you are writing extremely complicate code. In such extreme circumstances, the explicit locking mechanism offers a much better array of features than the standard synchronized keyword. So, the simple answer is “Take a judgment call based on the scenario. If you want to keep it simple, use the Synchronized keyword and for complicated scenarios use explicit locking”

At the end of the day, which technique to use is often a matter of personal preference.

Previous: Lock Scope

Next: Nested Locks

Chapter 11: Lock Scope


Now that we know how object locking works, the next topic to understand is the lock scope. Just like variable scope, locks too have a scope. However, this can be understood only in terms of explicit locking using the concepts we learnt in the previous chapter on “Explicit Locking

Since the lock() and unlock() method calls are explicit, we can move them anywhere, establishing any lock scope, from a single line of code to a scope that spans multiple methods and objects. By providing the means of specifying the scope of the lock, we can now move time-consuming and threadsafe code outside of the lock scope. And we can now lock at a scope that is specific to the program design instead of the object layout.

To put it simply, the lines of code between the lock() and unlock() methods is the scope of the lock that is being acquired.
Synchronized Blocks

It is possible for the synchronized keyword to lock a block of code within a method. It is also possible for the synchronized keyword to specify the object whose lock is grabbed instead of using the lock of the object that contains the method. Much of what we accomplish with the Lock interface can still be done with the synchronized keyword. It is possible to lock at a scope that is smaller than a method, and it is possible to create an object just so that it can be used as an synchronization object.

A Synchronized Block would look like below:
// lots of code
synchronized(this) {
// Code to be synchronized
}
// lots more code

This syntax of the synchronized keyword requires an object whose lock is obtained. Here we are using the this object. Using this syntax, we can now lock individual lines of code instead of the whole method. We can also share data across multiple objects by locking on other objects instead, such as the data object to be shared.

After reading this chapter, you may be wondering “How different are Synchronized Methods from Synchronized Blocks?”

Well, the answer my friend is that, a synchronized method and block work the same way. The scope of the lock is the only difference. Using synchronized blocks, we can implement synchronization at a higher/granular level for only a few lines of code instead of the whole method. Apart from this, they work in exactly the same way.

Previous: Explicit Locking

Next: Choosing a Locking Mechanism

Chapter 10: Explicit Locking of Objects


In the previous chapters we learnt about the “Synchronized Keyword” and how the whole “Synchronization & Race Condition” concept works. To recap, the purpose of the synchronized keyword is to provide the ability to allow serialized entrance to synchronized methods in an object. Although almost all the needs of data protection can be accomplished with this keyword, it is too primitive when the need for complex synchronization arises. More complex cases can be handled by using classes that achieve similar functionality as the synchronized keyword.

Using the Synchronized keyword automatically captures & releases locks when threads execute. But, starting J2SE 5.0, a developer can explicitly capture and release locks on objects. Sounds cool doesn’t it? This is exactly what we are going to learn in this chapter.

The synchronization tools in J2SE 5.0 implement a common interface: the Lock interface. For this chapter, the two methods of this interface that are important to us are lock( ) and unlock(). Using the Lock interface is similar to using the synchronized keyword: we call the lock() method at the start of the method and call the unlock() method at the end of the method, and we've effectively synchronized the method.

The lock() method grabs the lock. The difference is that the lock can now be more easily envisioned, we now have an actual object that represents the lock. This object can be stored, passed around, and even discarded. As before, if another thread owns the lock, a thread that attempts to acquire the lock waits until the other thread calls the unlock() method of the lock. Once that happens, the waiting thread grabs the lock and returns from the lock( ) method. If another thread then wants the lock, it has to wait until the current thread calls the unlock() method.

In terms of functionality, the code works exactly the same way as it would work with the Synchronized keyword. But, there is a minor difference. The difference is that by using a lock class, we can now utilize other functionality, that can't be accomplished by just using the synchronized keyword.

Using a lock class, we can now grab and release a lock whenever desired. We can test conditions before grabbing or releasing the lock. And since the lock is no longer attached to the object whose method is being called, it is now possible for two objects to share the same lock. It is also possible for one object to have multiple locks. Locks can be attached to data, groups of data, or anything else, instead of just the objects that contain the executing methods.

This is the cool advantage of using “Explicit Locking”.

The Lock Interface

Before we wrap up this chapter, let's look a little deeper into the Lock interface. The Lock interface code would look like below:
public interface Lock {
void lock( );
void lockInterruptibly( ) throws InterruptedException;
boolean tryLock( );
boolean tryLock(long time, TimeUnit unit)
throws InterruptedException;
void unlock( );
Condition newCondition( );
}

Lets understand the key methods of this class that we will use in real life:

lock() – this is the method you will use to obtain the lock. If the lock is not available, it waits until the lock is available.
tryLock() – this method is similar to the lock() method but, if the lock is not available, it does not wait and returns a boolean value of false. If the lock is obtained, it returns true
tryLock(long time, TimeUnit unit) – this method is similar to the tryLock() method with a small difference. You can specify the time period that this method has to wait, in case a lock is not available right away. The time passed as argument is the maximum time this method will wait for the lock
unlock() – this method is used to release/relenquish the lock

Previous: Race Conditions

Next: Lock Scope

Tuesday, January 3, 2012

Chapter 9: Race Conditions


In the previous chapters, we looked at the basic concepts of Java Multithreading like What a Thread is, the Synchronized Keyword, the volatile keyword etc. In this chapter, we are going to look at a more complex topic “Race Conditions”

When does a Race Condition Occur?

A race condition occurs when the order of execution of two or more threads may affect some variable or outcome in the program. It may turn out that all the different possible orders of thread execution have the same final effect on the program. The effect caused by the race condition may be insignificant and may not even be relevant.

The timing of the threading system may be such that the race condition never manifests itself, despite the fact that it exists in the code.

Race conditions can be considered harmless if you can prove that the result of the race condition is always the same. This is a common technique in some of Java's core classes. But in general, a race condition is a problem that is waiting to happen. Simple changes in the algorithm can cause race conditions to manifest themselves in problematic ways. Since different virtual machines have different ordering of thread execution, the developer should never let a race condition exist even if it is currently not causing a problem on the development system.

The next logical question that might arise in your mind is “Can properly Synchronizing two methods, prevent a race condition from happening?”

Well, the simple answer would be “Yes”. As explained in the previous chapter on “Synchronized keyword” synchronizing a method has the effect of serializing access to the method. This means that it is not possible to execute the same method in one thread while the method is already running in another thread. The implementation of this mechanism is done by a lock that is assigned to the object itself. The reason another thread cannot execute the same method at the same time is that the method requires the lock that is already held by the first thread. If two different synchronized methods of the same object are called, they also behave in the same fashion because they both require the lock of the same object, and it is not possible for both methods to grab the lock at the same time. In other words, even if two or more methods are involved, they are never run in parallel in separate threads.

Lets say there are two threads thread 1 and thread 2. If both these threads are attempting to acquire a lock on some object say Obj and if thread 1 acquires it first, thread 2 has to wait until thread 1 is done with all its processing before it can continue to execute.

An important point to remember here is that the lock is based on a specific instance of an object and not on any particular method or class.

Now that we know how synchronization works at a high level, the next logical question that might arise in your mind is ”How will a synchronized method behave in conjunction with a non-synchronized method?”

To answer this question, we must remember that all synchronizing does is to grab an object lock. This, in turn, provides the means of allowing only one synchronized method to run at a time, which in turn provides the data protection that solves the race condition. Simply put, a synchronized method tries to grab the object lock, and an unsynchronized method doesn't. This means that unsynchronized methods can execute at any time, by any thread, regardless of whether a synchronized method is currently running. At any given moment on any given object, any number of unsynchronized methods can be executing, but only one synchronized method can be executing.

A point to note here is that, if a non-synchronized method and a synchronized method are trying to update the same object, we may end up with unstable or inconsistent data. So, it is always a good idea to synchronize all key methods that modify important data that may be accessed by multiple threads at once.

Before we wrap up this chapter, another important question that might arise in your mind (if you are a person who has used Java for atleast a few years) is “How would Synchronization work with Static Methods?”

Ok, before we answer this question, do you understand the nuances of the static keyword and how it works when paired with methods or variables? If not, I strongly suggest you go to the topic on the “Static Keyword” and refresh your memory to understand the answer better.

Whenever we talk about threads and synchronization, we always talk about "obtaining the object lock." But, what about static methods? When a synchronized static method is called, which object are we referring to? A static method does not have a concept of the “this” object reference. It is not possible to obtain the object lock of an object that does not exist. So how does synchronization of static methods work? To answer this question, we need to understand the concept of a class lock. Just as there is an object lock that can be obtained for each instance of a class (i.e., each object), there is a lock that can be obtained for each class. We refer to this as the class lock. In terms of implementation, there is no such thing as a class lock, but it is a useful concept to help us understand how all this synchronization funda works.

When a static synchronized method is called, the program obtains the class lock before calling the method. This mechanism is identical to the case in which the method is not static; it is just a different lock. And this lock is used solely for static methods. Apart from the functional relationship between the two locks, they are not operationally related at all. These are two distinct locks. The class lock can be grabbed and released independently of the object lock.

Trivia:
If a nonstatic synchronized method calls a static synchronized method, it acquires both locks.

As mentioned, a class lock does not actually exist. The class lock is the object lock of the Class object that models the class. Since there is only one Class object per class, using this object achieves the synchronization for static methods.

From the perspective of a developer who creates multi-threaded enterprise applications, this whole concept can be summarized as follows:
Only one thread can execute a synchronized static method per class. Only one thread per instance of the class can execute a nonstatic synchronized method. Any number of threads can execute nonsynchronized methods, static or otherwise.

Previous: The Volatile Keyword

Next: Explicit Locking
© 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