Showing posts with label Concurrent Programming. Show all posts
Showing posts with label Concurrent Programming. Show all posts

Monday, January 30, 2012

Daemon Threads in Java

In normal circumstances, a Thread in executed until either it reaches the end of its void run() method or until void stop() is called (this method is deprecated and it's not recommended to use because it may trigger ThreadDeath errors).

Daemon threads are service providers for user-created threads. The main difference between daemon threads and non-daemon threads is that an application will end if the only remaining threads are daemon threads. The application will not end if there is at least one non-daemon thread running.

Any thread can become a daemon thread if one uses the method void setDaemon(boolean isDaemon). It is imperative to call this method before starting the thread. To check if a thread is a daemon thread you can simply call the method boolean isDaemon().

Also, it is to note that the void run() method must contain an infinite loop if you want your daemon thread to provide services as long as your application is opened.

Here's an example:
public class DaemonThread extends Thread
{
 public DaemonThread(String name)
 {
  super(name);
  this.setDaemon(true);
  this.start();
 }
 
 public void run()
 {
  while(true) //Keeps the daemon running
  {
   System.out.println("I am the Daemon " + getName() + "!");
   try 
   {
    Thread.sleep(100);
   } catch (InterruptedException e){}
  }
 }
}

Producer-Consumer Problem in Java

The producer-consumer problem is a "classic" multiprocessing problem involving two or more processes and a common resource who is a fixed-size buffer. The producer processes put data into the buffer and the consumer processes pop the data out of the buffer.

This processes need to be synchronized so the producers will not try to put data into the buffer when the buffer is full and consumer processes will not try to pop data out of the buffer when the buffer is empty.

In Java the synchronization can be achieved using the synchronized keyword. When a thread enters a synchronized method, it will activate a lock on that method so no other thread may enter it. The lock will be deactivated when the thread reaches the end of that method.

First we shall create the BufferResource class who will act similar to a stack:
public class BufferResource 
{
 private int[] buffer;
 private int lastIndex;
 private boolean isFull;
 
 public BufferResource(int size)
 {
  isFull = false;
  lastIndex = 0;
  buffer = new int[size];
 }
 
 public synchronized void pushData(int data)
 {
  while(isFull==true)
  {
   try
   {
    wait();
   }catch(InterruptedException ex){}
  }
  buffer[lastIndex] = data;
  lastIndex++;
  if(lastIndex>=buffer.length)
  {
   isFull=true;
   notifyAll();
  }
 }
 
 public synchronized int popData()
 {
  while(isFull==false)
  {
   try
   {
    wait();
   }catch(InterruptedException ex){}
  }
  lastIndex--;
  if(lastIndex==0)
  {
   isFull = false;
   notifyAll();
  }
  return buffer[lastIndex];
 }
}
The resource class contains an array to hold the data called buffer, an index called lastIndex to help pushing and popping and a boolean flag that will be set/unset when the lastIndex will be equal to the size of the array, respectively when lastIndex will be equal to zero.

The method void pushData(int data) will be called by the Producer class and will be used to fill the array with data. If the array is full, the Producer thread who entered the method will be blocked. When the last element of the array will be filled with data, the consumer threads will be waked up.

The method int popData() will be called by the Consumer class and will be used to remove data from the array. If the array is not full, the Consumer thread who entered the method will be blocked. When the array will be empty (after all data been popped), the producer threads will be waked up.

The Producer class will be implemented as:
public class Producer extends Thread
{
 private BufferResource buffer;
 private int iterations;
 
 public Producer(String name, int iterations, BufferResource buffer)
 {
  super(name);
  this.buffer = buffer;
  this.iterations = iterations;
 }
 
 public void run()
 {
  for(int i=0;i<iterations;i++)
  {
   buffer.pushData(i);
   System.out.println(this.getName() + " pushed " + i);
   try 
   {
    Thread.sleep((long)(Math.random()*1000));
   } catch (InterruptedException e) {}
  }
 }
}
The Producer class extends Thread and by doing so it needs to implement the interface Runnable. A Producer object needs to hold a reference to the common resource and may also hold a variable which specifies how many iterations it will do.

The Producer void run() method contains all the logic for a producer thread. The producer will push data into the buffer according to the specified number of iterations. After each push it will take a break for a random amount of time (maximum 1 second).

The Consumer class will be implemented as:
public class Consumer extends Thread
{
 private BufferResource buffer;
 private int iterations;
 
 public Consumer(String name, int iterations, BufferResource buffer)
 {
  super(name);
  this.buffer = buffer;
  this.iterations = iterations;
 }
 
 public void run()
 {
  for(int i=0;i<iterations;i++)
  {
   int val = buffer.popData();
   System.out.println(this.getName() + " poped " + val);
   try 
   {
    Thread.sleep((long)(Math.random()*1000));
   } catch (InterruptedException e) {}
  }
 }
}
The Consumer class is very similar to the Producer class. The main exception is that the Consumer will take data out of the buffer using BufferResource's method int popData().

The client for this application can be implemented as:
public class ProducerConsumerClient 
{
 public static void main(String args[])
 {
  BufferResource buffer = new BufferResource(5);
  Producer p1 = new Producer("Producer1",5,buffer);
  Producer p2 = new Producer("Producer2",5,buffer);
  Consumer c1 = new Consumer("Consumer1",5,buffer);
  Consumer c2 = new Consumer("Consumer2",5,buffer);
  p1.start();
  p2.start();
  c1.start();
  c2.start();
 }
}
It is very important to note, that in this implementation, in order to have all data consumed, the sum of iterations from the producers must be equal to the sum of iterations from the consumers.

If you try running the client, your output will be like:
Producer1 pushed 0
Producer2 pushed 0
Producer2 pushed 1
Producer2 pushed 2
Producer1 pushed 1
Consumer2 poped 1
Consumer1 poped 2
Consumer1 poped 1
Consumer2 poped 0
Consumer2 poped 0
Producer1 pushed 2
Producer2 pushed 3
Producer1 pushed 3
Producer2 pushed 4
Producer1 pushed 4
Consumer2 poped 4
Consumer1 poped 4
Consumer1 poped 3
Consumer2 poped 3
Consumer1 poped 2

Download source here.

Further reading:
Implementation of the Producer-Consumer using a BlockingQueue

Sunday, January 29, 2012

Creating Threads in Java

In Java, you can create a thread in two ways by:

1.Extending the Thread class

This is the easiest way to create a new thread. You simply need to create a new class which should inherit the Thread class from the java.lang package.

The Thread class implements the interface Runnable which contains the method void run(). The method void run() should contain all the actions and logic that your thread needs to perform.
public class MyThread extends Thread
{
 private int iterations;
 private long sleepTime;
 public MyThread(String s, int iterations, long sleepTime)
 {
  super(s);
  this.iterations = iterations;
  this.sleepTime = sleepTime;
 }
 public void run()
 {
  for(int i=0;i<iterations;i++)
  {
   System.out.println("Hi! My name is " 
         + this.getName() 
         + "! Iteration " + i);
   try
   {
    Thread.sleep(sleepTime);
   }catch(InterruptedException ex){}
  }     
 }
}
The class above takes as arguments the thread's name (which is transmitted to the superclass Thread), the number of iterations (practically how many times it will print a message) and a time in milliseconds which represents for how long the thread is going to wait after printing a message before starting another iteration.

As you probably already observed, the static void sleep(long timeInMilliseconds) method is called inside a try/catch block. The call must be done in this fashion because the sleep function throws an InterruptedException if the thread is interrupted by another thread.

You can create several threads of the type MyThread. Here's an example:
MyThread t1 = new MyThread("Slim",3,500);
MyThread t2 = new MyThread("Shady",2,250);
t1.start();
t2.start();
//Output
//Hi! My name is Slim! Iteration 0
//Hi! My name is Shady! Iteration 0
//Hi! My name is Shady! Iteration 1
//Hi! My name is Slim! Iteration 1
//Hi! My name is Slim! Iteration 2
It is very important to observe that a thread is started by calling the void start() method, NOT the void run() method which we implemented before.

2.Implementing the Runnable Interface

There are some cases where you may want your thread to inherit a specific object who doesn't inherit the Thread class. Since Java doesn't allow multiple inheritance you will not be able to inherit the object's class and the Thread class.
This problem can be solved by creating a subclass of your "specific object" that will also implement the Runnable interface.
Let us suppose that you have a class called CounterContext with the following implementation:
public class CounterContext 
{
 private int iterations;
 private long sleepTime;
 private String name;
 
 public CounterContext (String name, int iterations, 
         long sleepTime)
 {
  this.name = name;
  this.iterations = iterations;
  this.sleepTime = sleepTime;
 }
 
 public int getIterations(){return iterations;}
 public long getSleepTime(){return sleepTime;}
 public String getName(){return name;}
}
The subclass who will inherit CounterContext will implement the Runnable interface.
public class MyNewThread extends CounterContext implements Runnable
{
 public MyNewThread(String name, int iterations, long sleepTime)
 {
  super(name,iterations,sleepTime);
 }
 
 public void run() 
 {
  int iterations = getIterations();
  long sleepTime = getSleepTime();
  for(int i=0;i<iterations;i++)
  {
   System.out.println("Hi! My name is " 
         + this.getName() 
         + "! Itteration " + i);
   try
   {
    Thread.sleep(sleepTime);
   }catch(InterruptedException ex){}
  }  
 }
}
The MyNewThread does exactly the same thing as MyThread, except that MyNewThread will not be able to run as a thread by itself, but can serve as a constructor argument for a Thread object. The newly created Thread object will behave exactly like a MyThread object (since the void run() methods are almost identical for both MyNewThread and MyThread).
Thread t1 = new Thread(new MyNewThread("Slim",3,500));
Thread t2 = new Thread(new MyNewThread("Shady",2,250));
t1.start();
t2.start();
//Output
//Hi! My name is Slim! Itteration 0
//Hi! My name is Shady! Itteration 0
//Hi! My name is Shady! Itteration 1
//Hi! My name is Slim! Itteration 1
//Hi! My name is Slim! Itteration 2

Tuesday, October 18, 2011

Working with Timers in Java

The Java Timer class is very important and useful when you have to create a real-time application. To create a timer you need specify a task that will be performed when the time conditions are met.

To set the time conditions and the task (which can be implemented using a nested class) you will need to call the schedule or the scheduleAtFixedRate method. You also can set an delay for the timer. The signatures for this methods are:
  • schedule(TimerTask task, Date time)
    • specifies the task and the date of execution for your task. If the date has passed, the task will be executed imediately
  • schedule(TimerTask task, Date firstTime, long period)
    • specifies the task, the date of first execution (also, if the date passed, the task will be executed imediately). The task will be executed repeatedly according to the period (which is specified in milliseconds).
  •  schedule(TimerTask task, long delay)
    • specifies the task and the delay in milliseconds until the task is executed. The task will fire only once.
  •  schedule(TimerTask task, long delay, long period)
    • specifies the task and the delay in milliseconds until the task is executed for the first time. The task will be executed repeatedly according to the period (specified as well in milliseconds).
  •  scheduleAtFixedRate(TimerTask task, Date firstTime, long period)  
    • has the same logic as schedule(TimerTask task, Date firstTime, long period), except it is optimized for tasks that need to respect the time conditions in the long run.
  •  scheduleAtFixedRate(TimerTask task, long delay, long period)
    • has the same logic as schedule(TimerTask task, long delay, long period), except it is optimized for tasks that need to respect the time conditions in the long run.
The main difference between the recurring schedule and scheduleAtFixedRate is that schedule is better for shorter  tasks like repainting a component, changing the text of a label, etc, while scheduleAtFixedRate is when you deal with absolute time (which if different from your application time)

This means that sometimes the execution of your application will be delayed by the garbage collector or some other background activity. The schedule method will not care about this delays and will continue doing the job at its own pace (this is the application time), while the scheduleAtFixedRate will reduce its period to compensate for the "external" delays, so that the absolute timing will be preserved.

So, practically, if you have a task that repeats itself every second for 10 seconds and you will use schedule, the entire execution time may be 12 or 15 seconds according to the external delays. If you use scheduleAtFixedTime, the program execution will always take 10 seconds, even if that means that the task will be repeated 3 times in second to compensate the external delays.

Bellow, I've wrote an example on how to use the Timer class to count 10 seconds and print to console the number of seconds that passed every second.
import java.util.Timer;
import java.util.TimerTask;

public class SecondsCounter 
{
    private static final int SECOND = 1000;
    private int counter, seconds;
    private Timer t1;

    private class CountSecondsTimerTask extends TimerTask
    {
        public void run()
        {
            System.out.println(counter);
            if(counter==seconds)
                SecondsCounter.this.t1.cancel(); //Kill the timer
            counter++;
        }
    }
 
    public SecondsCounter(int seconds)
    {
        this.seconds = seconds;
        this.counter = 0;
        t1 = new Timer(); //Creates new timer
        t1.schedule(new CountSecondsTimerTask(), 0, SECOND); //Schedule timer
    }
}
Related Posts Plugin for WordPress, Blogger...