Saturday, September 29, 2007

Introducing PHP 5's Standard Library

Much of the buzz surrounding PHP5 has focused on its new object-oriented syntax and capabilities, and comparisons with Java. While all that was going on, the promisingly named "Standard PHP Library" (SPL) extension quietly made its way into the core PHP 5 distribution.

Although work is still in progress, the Standard PHP Library's current offering significantly increases the chances of getting PHP developers to agree on something (thereby increasing the chances of code re-use). It may also make your cunningly constructed class interface very easy for other people to use, as the SPL extension makes it possible to "overload" basic PHP syntax and make objects look like normal PHP arrays.

In this tutorial, I'll introduce the functionality available with the SPL extension and PHP5 with just enough examples to get you started. Be warned: PHP5's syntax will be used. If you need to catch up, try SitePoint's PHP5 review.

Today's iterations:

  • Introducing the SPL: what's it all about?
  • Looping the Loop: did someone say Iterator?
  • Iterations foreach of us: the "wow" factor
  • Admiring the Tree: a short tour of SPL classes and interfaces
  • Objects as Arrays: easier for your web page designer
  • The Big Deal: why you gotta like it

Don't for get to download all the code included in this article for your own use.

Introducing the SPL

The "Standard PHP Library" is a PHP extension developed by Marcus Boerger which (as the manual says) "is a collection of interfaces and classes that are meant to solve standard problems." As part of the core distribution of PHP5, it should be "always on".

If you've been around the block with PHP4, you'll know there are a few areas in which wheels are perpetually re-invented by almost every new PHP project. Standardizing some of the fundamentals is a good way to get PHP developers singing from the same sheet, and increases the chances of our being able to re-use code from Project X in Project Y.

Today the SPL extension addresses a single subset of problems: Iterators. What makes the SPL Iterator implementation interesting is not only that it defines a standard for everyone to use in PHP5, but also that it "overloads" certain parts of PHP syntax such as the foreach construct and basic array syntax, making it easier to work with objects of your classes.

Looping the Loop

So, what is an Iterator? In this context, Iterator refers to a software "design pattern", identified by the "Gang of Four" in their ground-breaking Design Patterns book.

The intent of an Iterator is to "provide an object which traverses some aggregate structure, abstracting away assumptions about the implementation of that structure."

As with all general definitions, the exact meaning of this statement may be none too clear at first glance.

By "aggregate structure" we're basically talking about anything you might "loop over" in PHP, such as the rows in a database result set, a list of files in a directory or each new line in a text file.

Using "normal" PHP, you might use the following to loop through a MySQL query:

// Fetch the "aggregate structure"
$result = mysql_query("SELECT * FROM users");

// Iterate over the structure
while ( $row = mysql_fetch_array($result) ) {
// do stuff with the row here
}

To read the contents of a directory, you might use:

// Fetch the "aggregate structure"
$dh = opendir('/home/harryf/files');

// Iterate over the structure
while ( $file = readdir($dh) ) {
// do stuff with the file here
}

And to read the contents of a file, you might use:

// Fetch the "aggregate structure"
$fh = fopen("/home/hfuecks/files/results.txt", "r");

// Iterate over the structure
while (!feof($fh)) {

$line = fgets($fh);
// do stuff with the line here

}

A glance at the above examples shows that they're very similar. Although each one works with a different type of resource, and uses PHP functions specific to that resource, the mantra is simple: "fetch resource; loop over contents".

If it was somehow possible to "abstract out" the specific PHP functions from the above examples and use some kind of generic interface instead, it might be possible to make the job of looping over the data look the same, irrespective of the type of resource that was being used. With no requirement to modify the loop for a different data source, it may be possible for the code in which the loop appears (perhaps a function that generated an HTML list) to be reused elsewhere.

That's where an Iterator comes in. The Iterator defines an abstract interface for use by your code. Specific implementations of the Iterator take care of each different type of structure with which you want to work, without the code that uses the Iterator having to care about the details.

That's the basic theory of Iterators. If you're interested to know more, you'll find starting points at the C2 Wiki and Wikipedia. More thoughts from me can be found at phpPatterns on the Iterator Pattern and in The PHP Anthology - Volume II, Applications.

Iterations foreach of Us

So what's so exciting about the SPL Iterators? Well, if you've written more than a line or two of PHP, you've probably run into the foreach construct, which is used to make easy work of looping through an array:

// A list of colors
$colors = array (
'red',
'green',
'blue',
);

foreach ( $colors as $color ) {
echo $color.'
';
}

Wouldn't it be nice if all loops where that easy, irrespective of whatever it was that you were looping over?

How about this?

valid();
}
return TRUE;
}
return FALSE;
}

function rewind() {
parent::rewind();
}
}

// Create a directory reader for the current directory
$Reader = new DirectoryReader('./');

// Loop through the files in the directory ?!?
foreach ( $Reader as $Item ) {
echo $Item.'
';
}
?>

Filename: directoryreader.php

If you ignore the class itself for a moment and look at the last few lines, you'll see that I've used the DirectoryReader object right there in the foreach loop. I've pulled items from it without having to call any of its methods! So long as you obey certain rules (which I'll get to shortly), the SPL extension allows to iterate over your own classes (where appropriate) in just the same way.

In fact, with the above example, I've jumped in at the deep end! Let's take a few steps back so I can explain what really happened here.

Iteration with SPL

Now that your appetite is whet, you first need to be warned that the PHP manual currently lacks the capabilities needed to fully document the SPL extension. It's geared primarily to documenting native functions, and lacks a clear means to fully describe something like an in-built class; interfaces fail even to get a mention.

Instead, you'll need to look at the generated documentation Marcus maintains, and trawl the source under CVS. Be aware also that the SPL extension is a moving target that's being actively developed and expanded. The code in this tutorial was tested under PHP 5.0.1, but if you're reading at a significantly distant point in the future, you may find parts of this code outdated.

The SPL extension defines a hierarchy of classes and interfaces. Some of these will already be loaded in your PHP5 installation (see what get_declared_classes() turns up). They correspond the interface and class definitions defined here and here (the PHP files found here should disappear eventually, once Marcus has time to implement them in C). Some of classes found in the examples directory (with the .inc extension) also form part of the hierarchy, but are not loaded by default; if you wish to use them, you'll need to make sure copies for inclusion are located somewhere in your PHP include path. More examples of the classes' use can be found with the tests while independent examples can be found at http://www.wiki.cc/php/PHP5#Iterators.

Although the number of classes and interfaces in the hierarchy may be daunting at first, don't panic! Basic use of the iterators requires only a single interface. If you're new to the idea of interfaces, have a look at this discussion of interfaces on SitePoint.

I'll summarize the purpose of all the pre-loaded classes and interfaces later in this tutorial, for you to browse at your leisure. Once you start to grasp what's on offer, you'll realize that Marcus has done an amazing job of addressing the most common, loop-related problems that recur in PHP. Life will get easier...

Let's return to the DirectoryReader example. How was it that I was able to iterate over my DirectoryReader object using foreach? The magic comes from the class I extended from, DirectoryIterator, which implements an interface called Iterator that's defined by the SPL extension.

Any class I write that implements the Iterator interface can be used in a foreach loop (note that this article explains how this works from the point of view of PHP internals). The Iterator interface is defined as follows:

interface Iterator extends Traversable {

/**
* Rewind the Iterator to the first element.
* Similar to the reset() function for arrays in PHP
* @return void
*/
function rewind();

/**
* Return the current element.
* Similar to the current() function for arrays in PHP
* @return mixed current element from the collection
*/
function current();

/**
* Return the identifying key of the current element.
* Similar to the key() function for arrays in PHP
* @return mixed either an integer or a string
*/
function key();

/**
* Move forward to next element.
* Similar to the next() function for arrays in PHP
* @return void
*/
function next();

/**
* Check if there is a current element after calls to rewind() or next().
* Used to check if we've iterated to the end of the collection
* @return boolean FALSE if there's nothing more to iterate over
*/
function valid();

}

Note that the SPL extension registers the Traversable interface from which Iterator inherits with the Zend Engine to allow the use of foreach. The Traversable interface is not meant to be implemented directly in PHP, but by other built-in PHP classes (currently, the SimpleXML extension does this; the SQLite extension probably should do this but, right now, it talks directly to the Zend API).

To implement this interface, your class must provide all of the methods defined above.

To show you how this works, I'll start by re-inventing the wheel and implementing an Iterator for native PHP arrays. Obviously, this is a pointless exercise, but it helps us understand how it works without getting lost in specific details.

To begin, I define a class to manage the iteration:

/**
* An iterator for native PHP arrays, re-inventing the wheel
*
* Notice the "implements Iterator" - important!
*/
class ArrayReloaded implements Iterator {

/**
* A native PHP array to iterate over
*/
private $array = array();

/**
* A switch to keep track of the end of the array
*/
private $valid = FALSE;

/**
* Constructor
* @param array native PHP array to iterate over
*/
function __construct($array) {
$this->array = $array;
}

/**
* Return the array "pointer" to the first element
* PHP's reset() returns false if the array has no elements
*/
function rewind(){
$this->valid = (FALSE !== reset($this->array));
}

/**
* Return the current array element
*/
function current(){
return current($this->array);
}

/**
* Return the key of the current array element
*/
function key(){
return key($this->array);
}

/**
* Move forward by one
* PHP's next() returns false if there are no more elements
*/
function next(){
$this->valid = (FALSE !== next($this->array));
}

/**
* Is the current element valid?
*/
function valid(){
return $this->valid;
}
}

Filename: arrayreloaded.php

Notice the "implements Iterator" at the start. This says I'm agreeing to abide by the Iterator "contract" and will provide all the required methods. The class then provides implementations of each method, performing the necessary work using PHP's native array functions (the comments explain the detail).

There are a couple of points of the Iterator's design that are worth being aware of when you write your own. The current() and key() Iterator methods could be called multiple times within a single iteration of the loop, so you need to be careful that calling them doesn't modify the state of the Iterator. That's not a problem in this case, but when working with files, for example, the temptation may be to use fgets() inside the current() method, which would advance the file pointer.

Otherwise, remember the valid() method should indicate whether the current element is valid, not the next element. What this means is that, when looping over the Iterator, we'll actually advance one element beyond the end of the collection and only discover the fact when valid() is called. Typically, it will be the next() and rewind() methods that actually move the Iterator and take care of tracking whether the current element is valid or not.

I can now use this class as follows:

// Create iterator object
$colors = new ArrayReloaded(array ('red','green','blue',));

// Iterate away!
foreach ( $colors as $color ) {
echo $color."
";
}

It's very easy to use! Behind the scenes, the foreach construct calls the methods I defined, beginning with rewind(). Then, so long as valid() returns TRUE, it calls current() to populate the $color variable, and next() to move the Iterator forward one element.

As is typical with foreach, I can also populate another variable with the value returned from the key() method:

// Display the keys as well
foreach ( $colors as $key => $color ) {
echo "$key: $color
";
}

Of course, nothing requires me to use foreach. I could call the methods directly from my code, like so:

// Reset the iterator - foreach does this automatically
$colors->rewind();

// Loop while valid
while ( $colors->valid() ) {

echo $colors->key().": ".$colors->current()."
";
$colors->next();

}

This example should help you see what foreach actually does to your object.

Note that the crude benchmarks I've performed suggest that calling the methods directly is faster than using foreach, because the latter introduces another layer of redirection that must be resolved at runtime by PHP.

Admiring the Tree

Now you've seen how to write a basic Iterator, it's worth summarizing the interfaces and classes offered internally by the SPL extension, so that you know what their jobs are. This list may change in future, but it summarizes what's on offer right now.

Interfaces

  • Traversable: as mentioned above, this is an Iterator interface for PHP internals. Unless you're writing an extension, ignore this.
  • Iterator: as you've seen, this defines the basic methods to iterate forward through a collection.
  • IteratorAggregate: if you would rather implement the Iterator separately from your "collection" object, implementing Iterator Aggregate will allow you to delegate the work of iteration to a separate class, while still enabling you to use the collection inside a foreach loop.
  • RecursiveIterator: this defines methods to allow iteration over hierarchical data structures.
  • SeekableIterator: this defines a method to search the collection that the Iterator is managing.
  • ArrayAccess: here's another magic interface with a special meaning for the Zend engine. Implementing this allows you to treat your object like an array with normal PHP array syntax (more on this below).

Classes

  • ArrayIterator: this Iterator can manage both native PHP arrays and the public properties of an object (more on this shortly).
  • ArrayObject: this unifies arrays and objects, allowing you to iterate over them and use array syntax to access the contents. See "Objects as Arrays" below (we'll grow our own class with similar behaviour).
  • FilterIterator: this is an abstract class that can be extended to filter the elements that are being iterated over (perhaps removing unwanted elements for a search).
  • ParentIterator: when using a ResursiveIterator, the ParentIterator allows you to filter out elements that do not have children. If, for example, you have a CMS in which documents can be placed anywhere under a tree of categories, the ParentIterator would allow you to recurse the tree but display only the "category nodes", omitting the documents that appear under each category.
  • LimitIterator: this class allows you to specify a range of elements to Iterator over, starting with a key offset and specifying a number of elements to access from that point. The concept is the same as the LIMIT clause in MySQL.
  • CachingIterator: this manages another Iterator (which you pass to its constructor). It allows you to check whether the inner Iterator has more elements, using the hasNext() method, before actually advancing with the next() method. Personally, I'm not 100% sure about the name; perhaps LookAheadIterator would be more accurate?
  • CachingRecursiveIterator: this is largely the same as the CachingIterator, but allows iteration over hierarchical data structures.
  • DirectoryIterator: to iterate over a directory in a file system, this Iterator provides a bunch of useful methods like isFile() and isDot() that save a lot of hassle.
  • RecursiveDirectoryIterator: this class allows iteration over a directory structure so that you can descend into subdirectories.
  • SimpleXMLIterator: this makes SimpleXML even simpler! Currently, the best examples can be found with the SPL tests -- see the files beginning "sxe_*"
  • RecursiveIteratorIterator: this helps you do cool stuff like "flatten" a hierarchical data structure so that you can loop through it with a single foreach statement, while still preserving knowledge of the hierarchy. This class could be very useful for rendering tree menus, for example.

To see it in action, try using the DirectoryTreeIterator (whichextendsRecursiveIteratorIterator), like so:

$DirTree = new

Friday, September 28, 2007

Neural network


Traditionally, the term neural network had been used to refer to a network or circuitry of biological neurons. The modern usage of the term often refers to artificial neural networks, which are composed of artificial neurons or nodes. Thus the term 'Neural Network' has two distinct connotations:

1. Biological neural networks are made up of real biological neurons that are connected or functionally-related in the peripheral nervous system or the central nervous system. In the field of neuroscience, they are often identified as groups of neurons that perform a specific physiological function in laboratory analysis.
2. Artificial neural networks are made up of interconnecting artificial neurons (usually simplified neurons) which may share some properties of biological neural networks. Artificial neural networks may either be used to gain an understanding of biological neural networks, or for solving traditional artificial intelligence tasks without necessarily attempting to model a real biological system.

Please see the corresponding articles for details on artificial neural networks or biological neural networks. This article focuses on the relationship between the two concepts.

Characterization


In general a biological neural network is composed of a group or groups of chemically connected or functionally associated neurons. A single neuron may be connected to many other neurons and the total number of neurons and connections in a network may be extensive. Connections, called synapses, are usually formed from axons to dendrites, though dendrodendritic microcircuits [1] and other connections are possible. Apart from the electrical signaling, there are other forms of signaling that arise from neurotransmitter diffusion, which have an effect on electrical signaling. As such, neural networks are extremely complex. Whilst a detailed description of neural systems is nebulous, progress is being charted towards a better understanding of basic mechanisms.
Simplified view of an artificial neural network
Simplified view of an artificial neural network

Artificial intelligence and cognitive modeling try to simulate some properties of neural networks. While similar in their techniques, the former has the aim of solving particular tasks, while the latter aims to build mathematical models of biological neural systems.

In the artificial intelligence field, artificial neural networks have been applied successfully to speech recognition, image analysis and adaptive control, in order to construct software agents (in computer and video games) or autonomous robots. Most of the currently employed artificial neural networks for artificial intelligence are based on statistical estimation, optimization and control theory.

The cognitive modelling field is the physical or mathematical modeling of the behaviour of neural systems; ranging from the individual neural level (e.g. modelling the spike response curves of neurons to a stimulus), through the neural cluster level (e.g. modelling the release and effects of dopamine in the basal ganglia) to the complete organism (e.g. behavioural modelling of the organism's response to stimuli).

The brain, neural networks and computers



Neural networks, as used in artificial intelligence, have traditionally been viewed as simplified models of neural processing in the brain, even though the relation between this model and brain biological architecture is debated. To answer this question, David Marr has proposed various levels of analysis which provide us with a plausible answer for the role of neural networks in the understanding of human cognitive functioning.

A subject of current research in theoretical neuroscience is the question surrounding the degree of complexity and the properties that individual neural elements should have to reproduce something resembling animal intelligence.

Historically, computers evolved from the von Neumann architecture, which is based on sequential processing and execution of explicit instructions. On the other hand, the origins of neural networks are based on efforts to model information processing in biological systems, which may rely largely on parallel processing as well as implicit instructions based on recognition of patterns of 'sensory' input from external sources. In other words, rather than sequential processing and execution, at their very heart, neural networks are complex statistic processors....

Neural networks and artificial intelligence



An artificial neural network (ANN), also called a simulated neural network (SNN) or commonly just neural network (NN) is an interconnected group of artificial neurons that uses a mathematical or computational model for information processing based on a connectionist approach to computation. In most cases an ANN is an adaptive system that changes its structure based on external or internal information that flows through the network.

In more practical terms neural networks are non-linear statistical data modeling or decision making tools. They can be used to model complex relationships between inputs and outputs or to find patterns in data.

Background



An artificial neural network involves a network of simple processing elements (artificial neurons) which can exhibit complex global behaviour, determined by the connections between the processing elements and element parameters. One classical type of artificial neural network is the Hopfield net.

In a neural network model, simple nodes (called variously "neurons", "neurodes", "PEs" ("processing elements") or "units") are connected together to form a network of nodes — hence the term "neural network". While a neural network does not have to be adaptive per se, its practical use comes with algorithms designed to alter the strength (weights) of the connections in the network to produce a desired signal flow.

In modern software implementations of artificial neural networks the approach inspired by biology has more or less been abandoned for a more practical approach based on statistics and signal processing. In some of these systems neural networks, or parts of neural networks (such as artificial neurons) are used as components in larger systems that combine both adaptive and non-adaptive elements.

Applications

The utility of artificial neural network models lies in the fact that they can be used to infer a function from observations. This is particularly useful in applications where the complexity of the data or task makes the design of such a function by hand impractical.


Real life applications



The tasks to which artificial neural networks are applied tend to fall within the following broad categories:

* Function approximation, or regression analysis, including time series prediction and modelling.
* Classification, including pattern and sequence recognition, novelty detection and sequential decision making.
* Data processing, including filtering, clustering, blind signal separation and compression.

Application areas include system identification and control (vehicle control, process control), game-playing and decision making (backgammon, chess, racing), pattern recognition (radar systems, face identification, object recognition and more), sequence recognition (gesture, speech, handwritten text recognition), medical diagnosis, financial applications, data mining (or knowledge discovery in databases, "KDD"), visualisation and e-mail spam filtering.

Neural network software


Neural network software is used to simulate, research, develop and apply artificial neural networks, biological neural networks and in some cases a wider array of adaptive systems.

Learning paradigms


There are three major learning paradigms, each corresponding to a particular abstract learning task. These are supervised learning, unsupervised learning and reinforcement learning. Usually any given type of network architecture can be employed in any of those tasks.

Supervised learning

In supervised learning, we are given a set of example pairs  (x, y), x \in X, y \in Y and the aim is to find a function f in the allowed class of functions that matches the examples. In other words, we wish to infer how the mapping implied by the data and the cost function is related to the mismatch between our mapping and the data.

Unsupervised learning



In unsupervised learning we are given some data x, and a cost function to be minimized which can be any function of x and the network's output, f. The cost function is determined by the task formulation. Most applications fall within the domain of estimation problems such as statistical modeling, compression, filtering, blind source separation and clustering.

Reinforcement learning


In reinforcement learning, data x is usually not given, but generated by an agent's interactions with the environment. At each point in time t, the agent performs an action yt and the environment generates an observation xt and an instantaneous cost ct, according to some (usually unknown) dynamics. The aim is to discover a policy for selecting actions that minimises some measure of a long-term cost, i.e. the expected cumulative cost. The environment's dynamics and the long-term cost for each policy are usually unknown, but can be estimated. ANNs are frequently used in reinforcement learning as part of the overall algorithm. Tasks that fall within the paradigm of reinforcement learning are control problems, games and other sequential decision making tasks.

Learning algorithms



There are many algorithms for training neural networks; most of them can be viewed as a straightforward application of optimization theory and statistical estimation.

Evolutionary computation methods, simulated annealing, expectation maximization and non-parametric methods are among other commonly used methods for training neural networks. See also machine learning.

Recent developments in this field also saw the use of particle swarm optimization and other swarm intelligence techniques used in the training of neural networks.

Neural networks and neuroscience


Theoretical and computational neuroscience is the field concerned with the theoretical analysis and computational modeling of biological neural systems. Since neural systems are intimately related to cognitive processes and behaviour, the field is closely related to cognitive and behavioural modeling.

The aim of the field is to create models of biological neural systems in order to understand how biological systems work. To gain this understanding, neuroscientists strive to make a link between observed biological processes (data), biologically plausible mechanisms for neural processing and learning (biological neural network models) and theory (statistical learning theory and information theory).

Types of models

Many models are used in the field, each defined at a different level of abstraction and trying to model different aspects of neural systems. They range from models of the short-term behaviour of individual neurons, through models of how the dynamics of neural circuitry arise from interactions between individual neurons, to models of how behaviour can arise from abstract neural modules that represent complete subsystems. These include models of the long-term and short-term plasticity of neural systems and its relation to learning and memory, from the individual neuron to the system level.

Current research

While initially research had been concerned mostly with the electrical characteristics of neurons, a particularly important part of the investigation in recent years has been the exploration of the role of neumodulator such as dopamine, acetylcholine, and serotonin on behaviour and learning.

References

  • Peter Dayan, L.F. Abbott. Theoretical Neuroscience. MIT Press.
  • Wulfram Gerstner, Werner Kistler. Spiking Neuron Models:Single Neurons, Populations, Plasticity. Cambridge University Press.

Java MultiThreading Tutorial

Multithreading is one of the most important concepts of the Java language. You simply cannot do without multithreading in real-world programming. Multithreading basically enables your program to do more than one task at once and also to synchronize the various tasks. But before we launch into multithreading we will briefly summarize the points about threads.
Brief Recapitulation of threads

There are two ways to create threads.

* Subclass Thread and override run()
* Implement Runnable and override run()

Either of these two approaches may be used. Since multiple inheritance doesn't allow us to extend more than one class at a time, implementing the Runnable interface may help us in this situation.

You call a thread by the start() method. And start calls the run() method. You never call run() directly. The stop() method is now deprecated and should be avoided. Threads have priorities between 1-10, the default being 5 i.e normal priority.

A daemon thread is a thread that has no other role other than to serve other threads. When only daemon threads remain, the program exits. When a new thread object is created, the new thread has priority equal to the creating thread, and is a daemon thread if and only if the creating thread is a daemon.

When the JVM starts, there is usually a single non-daemon thread which typically calls the main() method of the class.

Threads can be in one of four states.

* New Threads
When a thread is first created, the thread is not yet running.
* Runnable Threads
Once the start() method is invoked the thread is runnable and starts to run only when the code inside the run() method begins executing.
* Blocked Threads
Threads can enter the blocked state when any of these four conditions occur.
When sleep() is called.
When suspend() is called.
When wait() is called.
The thread calls an operation e.g. during input/output, which will not return until reading/writing is complete.
* Dead Threads
A thread dies because of two reasons.
It dies a natural death when the run() method exits.
It is killed because its stop() method was invoked.

Now it is time for some examples. Take a look at two examples below for creating more than one thread.


class NewThread extends Thread {
String name;
Thread t;

NewThread(String threadname) {
name=threadname;
t=new Thread(this, name);
System.out.println("New Thread: " + t );
t.start();
}

public void run() {
try {
for(int i=5; i>0;i--) {
System.out.println(name + ":" + i) ;
Thread.sleep(1000);
}
}
catch (InterruptedException e) {
System.out.println(name + " Interrupted. ");
}
System.out.println(name + " Exiting.");
}
}

class MultiThreadDemo {

public static void main (String args[]) {
new NewThread("One");
new NewThread("Two");
new NewThread("Three");

try {
Thread.sleep(10000);
}
catch (InterruptedException e) {
System.out.println("Main Thread Interrupted.");
}
System.out.println("main Thread Exiting.");
}
}

And the second one.

Note: Suspend and resume are deprecated methods.


class NewThread implements Runnable {
String name;
Thread t;

NewThread(String threadname) {
name=threadname;
t=new Thread(this, name);
System.out.println("New Thread: " + t);
t.start();
}

public void run() {
try {
for(int i=5;i>0;i--) {
System.out.println(name + ":" + i);
Thread.sleep(200);
}
}
catch (InterruptedException e) {
System.out.println(name + "Interrupted. ");
}

System.out.println(name + " Exiting.");
}
}

class SuspendResume {

public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");

try {
Thread.sleep(1000);
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.t.suspend();
System.out.println("Resuming thread One");
ob1.t.resume();

System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.t.suspend();
System.out.println("Resuming thread Two");
ob2.t.resume();
}
catch (InterruptedException e) {
System.out.println("main thread interrupted." );
}

try {
ob1.t.join();
ob2.t.join();
}
catch (InterruptedException e) {
System.out.println("main thread interrupted.");
}

System.out.println("Main thread Exiting.");
}
}
Synchronization

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time. The process by which this is achieved is synchronization.

Key to synchronization is the concept of the monitor. A monitor is an object that is used as a mutually exclusive lock. Only one thread can own the monitor at a given time. When a thread acquires a lock, it is said to have entered the monitor. The other threads attempting to enter the locked monitor will be suspended until the first exits the monitor.

There are two ways you can synchronize your code.

* synchronized methods.
* synchronized statement

Both involve the use of the synchronized keyword. See below for an example.


import java.io.*;

class Deposit {
static int balance = 1000;

public static void main(String args[]) {
PrintWriter out = new PrintWriter(System.out, true);
Account account = new Account(out);
DepositThread first, second;

first = new DepositThread(account, 1000, "#1");
second=new DepositThread(account, 1000, "\t\t\t\t#2");

first.start();
second.start();

try {
first.join();
second.join();
}
catch (InterruptedException e) { }

out.println("*** Final balance is " + balance);
}
}

class Account {
PrintWriter out;

Account(PrintWriter out) {
this.out=out;
}

synchronized void deposit(int amount, String name ) {
int balance;

out.println(name + " trying to deposit " + amount);
out.println(name + " getting balance... " );
balance=getBalance();
out.println(name + " balance got is " + balance);

balance += amount;

out.println(name + " setting balance...");
setBalance(balance);
out.println(name + " balance set to " + Deposit.balance);
}

int getBalance() {

try {
Thread.sleep(1000);
}
catch (InterruptedException e) { }

return Deposit.balance;
}

void setBalance(int balance) {
try {
Thread.sleep(1000);
}
catch(InterruptedException e) { }

Deposit.balance = balance;
}
}

class DepositThread extends Thread {
Account account;
int deposit_amount;
String message;

DepositThread(Account account, int amount, String message) {
this.message=message;
this.account=account;
this.deposit_amount=amount;
}
public void run() {
account.deposit(deposit_amount, message);
}
}


Note: What will happen if the synchronized keyword is removed in the preceding example ?
Inter-thread Communication

Java's inter-thread communication process involves the use of wait(), notify() and notifyall() methods. These methods are implemented as final methods in Object, so all classes have them. These methods can only be called from within synchronized code.

Rules for using these methods:

* wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify().
* notify() wakes up the first thread that called wait() on the object.
* notifyall() wakes up all the threads waiting on the object. The highest priority thread will run first.

See below for an incorrect implementation of a producer/consumer example.


//An incorrect implementation of a producer and consumer.

class Q {

int n;

synchronized int get() {
System.out.println("Got: " + n);
return n;
}
synchronized void put(int n) {
this.n=n;
System.out.println("Put: " + n);

}
}

class Producer implements Runnable {
Q q;

Producer(Q q) {
this.q=q;
new Thread(this, "Producer").start();
}
public void run() {
int i=0;

while(true) {
q.put(i++);
}
}
}

class Consumer implements Runnable {
Q q;

Consumer(Q q) {
this.q=q;
new Thread(this, "Consumer").start();
}

public void run() {
while(true) {
q.get();
}
}
}

class PC {
public static void main(String args[]) {
Q q = new Q();

new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop");
}
}


The correct way would be using wait() and notify() as shown here.


//A correct implementation of a producer and consumer.

class Q {

int n;
boolean valueset = false;

synchronized int get() {
if (!valueset)
try {
wait();
}
catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}

System.out.println("Got: " + n);
valueset=false;
notify();

return n;
}
synchronized void put(int n) {
if (valueset)
try {
wait();
}
catch(InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n=n;
valueset=true;
System.out.println("Put: " + n);
notify();
}
}

class Producer implements Runnable {
Q q;

Producer(Q q) {
this.q=q;
new Thread(this, "Producer").start();
}
public void run() {
int i=0;

while(true) {
q.put(i++);
}
}
}

class Consumer implements Runnable {
Q q;

Consumer(Q q) {
this.q=q;
new Thread(this, "Consumer").start();
}

public void run() {
while(true) {
q.get();
}
}
}

class PCFixed {
public static void main(String args[]) {
Q q = new Q();

new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop");
}
}


Now to summarize the points about multithreading: thread synchronization, inter-thread communication, thread priorities, thread scheduling, and daemon threads.