Friday, January 29, 2021

Name Mangling in Python With Examples

If you are writing a class in Python and want to follow Encapsulation OOPS concept in Python then how will you stop outside access to the variables as there are no explicit access modifiers like public, private, protected in Python and all the variables are public by default. In Python there is limited support for making class member private and that process is known as name mangling in Python.

Python name mangling mechanism

In name mangling mechanism any identifier with at least two leading underscores, at most one trailing underscore is textually replaced with _classname__identifier where classname is the current class name. For example if there is a variable __test in the class then it is replaced with _classname__test.

Since the name is changed internally by the interpreter so you can’t access the variable using its original name that’s how you get data hiding in Python.

Name mangling is helpful for letting subclasses override methods without breaking intraclass method calls.

Name mangling Python example

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user.__age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
Traceback (most recent call last):
  File "F:/knpcode/Python/Programs/NameMangling.py", line 16, in 
    print(user.__age)
AttributeError: 'User' object has no attribute '__age'

In the class User there is a field __age (declared with double underscores) when it is accessed using the class method that is OK but trying to access it directly results in an error as its name is changed to (_User__age) by the name mangling mechanism.

You can check the name change by using the dir() function which returns a list of valid attributes for the passed object.

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
print(dir(user))
Output
['_User__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
 '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__',
 '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
 '__subclasshook__', '__weakref__', 'display_user', 'name']

Here you can see that __age is changed to _User__age.

Name mangling with method names

Since any class member with at least two leading underscores, at most one trailing underscore is textually replaced with _classname__identifier so name mangling is applied to the method name too.

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def __display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
user.__display_user()
Output
Traceback (most recent call last):
  File "F:/knpcode/Python/Programs/NameMangling.py", line 12, in 
    user.__display_user()
AttributeError: 'User' object has no attribute '__display_user'

How to access name mangled variable

In name mangling process name is replaced with _classname__membername so you can still access the member name by using the mangled name. That’s why Python states that there is only limited support for making class member private.

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
# Accessing using the mangled name
print(user._User__age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
34

Python name mangling with method overriding

Name mangling is also helpful in method overriding in Python. It lets subclasses override methods without breaking intraclass method calls. Consider following example where class B extends class A and overrides parent class test method. In the init() of class A there is also a call to test method.

class A:
  def __init__(self):
    print('in init')
    self.test()

  def test(self):
    print('In test method of class A')


class B(A):
  def test(self):
    print('In test method of class B')


obj = B()
obj.test()
Output
in init
In test method of class B
In test method of class B

As you can see test() method of class B is getting called both of the times as the reference is of class B. But what you intended was to call test() method of class A when doing self.test(). To avoid breaking intraclass method calls in such scenario you can create a private copy of the original method.

class A:
  def __init__(self):
    print('in init')
    self.__test()

  def test(self):
    print('In test method of class A')
      
  # private copy
  __test = test

class B(A):
  def test(self):
    print('In test method of class B')


obj = B()
obj.test()
Output
in init
In test method of class A
In test method of class B

That's all for the topic Name Mangling in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Wednesday, January 20, 2021

Polymorphism in Python With Examples

In this post we’ll see the usage of OOPS concept Polymorphism in Python.

What is Polymorphism

Polymorphism is a Greek word where poly means “many” and morph means "change from one form to another". In object oriented terms it relates to the same object reference taking many forms (assigned different types), a method with the same name having more than one implementations, an operator behaving differently for different operands.

Polymorphism in Python

In an object oriented language you may see use of Polymorphism in one of the following ways

  • Method overloading, also known as compile time Polymorphism
  • Method overriding, also known as run time Polymorphism
  • Operator overloading

In Python you will find support for Polymorphism through Method overriding and Operator overloading. Python doesn't support method overloading in its traditional sense though. Also when discussing Polymorphism in Python you should also get to know about duck typing in Python. So let’s see some examples.

Compile time polymorphism (Method Overloading)

Method overloading means having multiple methods with the same name in a class. These overloaded methods differ in types or number of arguments passed.

Python doesn’t support compile time polymorphism or method overloading. If there are multiple methods with the same name in a class only the last defined method is recognized. Calling any other overloaded method results in an error.

Read more about Method Overloading in Python in this post- Method Overloading in Python With Examples

Runtime polymorphism (Method Overriding)

In case of inheritance child class inherits all the properties and methods of parent class. If there is a method in a child class that has the same name and same number of arguments as in parent class then this process is called method overriding where the child class method is said to be overriding the parent class method.

Read more about Method Overriding in Python in this post- Method Overriding in Python With Examples

When you call the overridden method with parent class object, method of the parent class is executed. When same method is called with child class object, method of the child class is executed. So the appropriate overridden method is called based on the object type, which is an example of run time polymorphism.

Consider the following class hierarchy where super class Animal has two methods info() and make_sound(). There are two child classes Duck and Dog overriding both of the methods.

class Animal:
  def info(self):
    print('I am an animal')

  def make_sound(self):
    pass


class Duck(Animal):
  def info(self):
    print('I am a Duck')

  def make_sound(self):
    print('Quack Quack')


class Dog(Animal):
  def info(self):
    print('I am a Dog')

  def make_sound(self):
    print('Bow Wow')


d = Duck()
d.info()
d.make_sound()
d = Dog()
d.info()
d.make_sound()
Output
I am a Duck
Quack Quack
I am a Dog
Bow Wow

When d refers to an object of Duck it calls the method of Duck class, when d refers to an object of Dog class it calls the method of that class.

Polymorphism in Python through operator overloading

Operator overloading is also an example of polymorphism where the same operator performs different operations based on the type of operands. Python supports operator overloading.

For example ‘+’ operator-

  • When used with numbers it performs addition operation.
  • When used with two strings concatenate those strings
  • When used with lists merge those lists
# + operator with integers- Addition
print(3 + 4)
# + operator with Strings- Concatenation
print("Operator " + "Overloading")
a = [10, 11, 12]
b = [100, 200, 300]
# + operator with Lists- Merging
print(a + b)
Output
7
Operator Overloading
[10, 11, 12, 100, 200, 300]

Duck typing and Polymorphism

Python follows the duck typing philosophy which states "If it walks like a duck, and it quacks like a duck, then it must be a duck".

In a dynamic language like Python it means that you don't worry about the type or the class of an object. You can perform the required action with the object or not is more important.

Because of this duck typing principle followed by Python it is possible to create a function that can take any object, allowing for polymorphism. As long as the passed object has the called method it can be called. Let’s clear it with an example where we have two classes with a method make_sound(). There is a function invoke which takes any object as an argument and calls the make_sound() method on that object. When invoke function is called with an object of class Duck make_sound() method of the Duck class is called, when it is called with an object of class Dog make_sound() method of the Dog class is called.

class Duck:
  def make_sound(self):
    print("Quack Quack")

class Dog:
  def make_sound(self):
    print('Bow Wow')

def invoke(obj):
  obj.make_sound()

d = Duck()
invoke(d)
d = Dog()
invoke(d)
Output
Quack Quack
Bow Wow

That's all for the topic Polymorphism in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Tuesday, January 19, 2021

Encapsulation in Python With Examples

In this post we’ll see the usage of OOPS concept Encapsulation in Python.

What is Encapsulation

Encapsulation is the process of keeping the data and the code (methods) that manipulates that data together as a unit. Any variable can only be changed through a method in the same class that way data is protected from any intentional or accidental modification by any outside entity.

A class is an example of encapsulation as it wraps all the variables and methods defined with in that class.

Encapsulation in Python

Since class is an example of Encapsulation so defining a class in Python which wraps all the variables and methods is first step towards encapsulation. But the question is how to stop outside access to the variables as there are no explicit access modifiers like public, private, protected in Python and all the variables are public by default. Here is an example to clarify it-

class User:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user.age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
34

As you can see name and age fields of the class User can be accessed through a class method as well as directly outside the class too.

How to control access in Python

As demonstrated through an example class fields can be accessed directly from outside the class in Python so how to control that access and how to have proper encapsulation in Python?

Python has the concept of using a variable prefixed with a single underscore (e.g. _name) and a variable prefixed with double underscores (e.g. __name) to give some semblance to controlling access with in a class.

Using single underscore

Prefixing a variable with a single underscore is merely a convention followed in Python code to show your intention that such a class member should be treated as a non-public part of the API (whether it is a function, a method or a data member). It is more of an indicator to other developers that such a class member should be used only with in the scope of the class and shouldn’t be accessed from outside the class.

Since using a single underscore is just a convention so it doesn’t actually change the access of the variable in any way.

class User:
  def __init__(self, name, age):
    self.name = name
    self._age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self._age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user._age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
34

You can see that the age variable is now prefixed with a single underscore but that can still be accessed outside the class. You will get this warning though ‘Access to a protected member _age of a class’.

Using double underscore

You can come closest to making a class member private in Python by prefixing it with double underscores. This process is known as name mangling in Python where any identifier of the form __var (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__var by the Python interpreter, where classname is the current class name.

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user.__age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
Traceback (most recent call last):
  File "F:/knpcode/Programs/Example.py", line 16, in 
    print(user.__age)
AttributeError: 'User' object has no attribute '__age'

Now the age variable is prefixed with double underscores which changes its name internally to _User__age thus it is not accessible from outside the class. From the method with in the class it is still accessible.

Note that using double underscores just change the name of the field so it is still possible to access or modify a variable that is considered private by using the changed name.

In the example you can change statement print(user.__age) to print(user._User__age) to access the changed name directly.

That's all for the topic Encapsulation in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Thursday, January 14, 2021

isinstance() in Python With Examples

isinstance() function in Python is used to check if the passed object is an instance of the specific class or not. isinstance() is a built-in function in Python.

Python isinstance() syntax

isinstance(object, classinfo)

Returns true if the object (first argument) is an instance of the classinfo (second argument) or any of its subclass. Function returns false if object is not an object of the given type.

classinfo can also be a tuple of type objects, in that case isinstance() function returns true of object is an instance of any of the types in a passed tuple.

If classinfo is not a type or tuple of types a TypeError exception is raised.

Python isinstance() examples

1. Using isinstance() with built-in types

i = 7
s = "knocode.com"
f = 5.67
print('Is i instance of int:', isinstance(i, int))
print('Is s instance of str:', isinstance(s, str))
print('Is f instance of float:', isinstance(f, float))
print('Is s instance of float:', isinstance(s, float))
Output
Is i instance of int: True
Is s instance of str: True
Is f instance of float: True
Is s instance of float: False

2. With list, dict and tuple

t = (2, 3, 4)
l = [1, 2, 3]
d = {'Name': 'Jack', 'Age': 27}
f = 56.78
print('Is t instance of tuple:', isinstance(t, tuple))
print('Is l instance of list:', isinstance(l, list))
print('Is d instance of dict:', isinstance(d, dict))
# tuple of types
print('Is f instance of any type:', isinstance(f, (str, int, float, tuple)))
Output
Is t instance of tuple: True
Is l instance of list: True
Is d instance of dict: True
Is f instance of any type: True

3. Using isinstance() with object

That’s where isinstance() function is more useful. Since Python is an object-oriented programming language so it supports inheritance and you can create a hierarchical structure of classes where a child class inherits from a parent class.

In the example Person is the super class and Employee is the sub-class inheriting from Person. Because of this inheritance Employee object is of type Employee as well as of Person. Person object is of type Person only. Let’s verify this with the help of isinstance() function.

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def display_info(self):
    print('In display_info method of Person class')
    print('Name:', self.name)
    print('Age:', self.age)


class Employee(Person):
  def __init__(self, person_id, department, name, age):
    super().__init__(name, age)
    self.person_id = person_id
    self.department = department

  def display_info(self):
    super().display_info()
    print('In display_info method of Employee class')
    print('Id:', self.person_id)
    print('Department:', self.department)

e = Employee(1, "IT", "Michael Weyman", 42)
p = Person("Amit Tiwari", 34)
print('e is an instance of Employee', isinstance(e, Employee))
print('e is an instance of Person', isinstance(e, Person))
print('p is an instance of Person', isinstance(p, Person))
print('p is an instance of Employee', isinstance(p, Employee))
Output
e is an instance of Employee True
e is an instance of Person True
p is an instance of Person True
p is an instance of Employee False

You might be thinking all this is OK but what benefit do I get by just checking whether isinstance() returns true or false.

Python is a dynamically typed language and type is implicitly assigned depending on the value passed. This function comes handy if you want to be sure if the called method is present for an object or not. Here note that if you call a method that is not present for the object AttributeError is raised at runtime.

Consider the following program-

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def display_info(self):
    print('In display_info method of Person class')
    print('Name:', self.name)
    print('Age:', self.age)


class Employee(Person):
  def __init__(self, person_id, department, name, age):
    super().__init__(name, age)
    self.person_id = person_id
    self.department = department

  def display_info(self):
    super().display_info()
    print('In display_info method of Employee class')
    print('Id:', self.person_id)
    print('Department:', self.department)


class Test:
  pass


def call_method(o):
  o.display_info()


e = Employee(1, "IT", "Michael Weyman", 42)
call_method(e)
t = Test()
call_method(t)

Another class Test is added and there is a method call_method which takes an object as argument and calls display_info() method on that object. For object of class Employee it will work fine but calling display_info() method on object of class T results in AttributeError.

Output
in call_method
    o.display_info()
AttributeError: 'Test' object has no attribute 'display_info'
In display_info method of Person class
Name: Michael Weyman
Age: 42
In display_info method of Employee class
Id: 1
Department: IT

In such scenario where you want to be sure if object is of certain type and call to the method is valid you can check the type of the object using isinstance(). You can change call_method to include isinstance() as given below-

def call_method(o):
    if isinstance(o, Person):
        o.display_info()

That's all for the topic isinstance() in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Wednesday, January 13, 2021

Abstraction in Python With Examples

In this post we’ll see the usage of OOPS concept Abstraction in Python.

What is Abstraction

Abstraction means hiding the complexity of the implementation and just exposing the essential features to the user. As an example you can take any electronics item where you interact with the product using buttons and switches to turn it on and off or increase and decrease the volume or speed. The real complexity, how that functionality is implemented is hidden from us.

In the context of object oriented programming Abstraction means exposing just the end points (methods) and hiding the real implementation from the end user.

Abstraction in Python

Abstraction in Python is achieved by using abstract classes and interfaces.

Abstract class is a class that contains one or more abstract methods. Abstract methods are the methods that don’t contain any implementation, sub classes that inherit from the abstract class should provide implementation for the abstract methods. Abstract class can have regular methods (methods with method body) too so you can say that Abstract class generally provides incomplete functionality providing implementation for the common methods while leaving the specific implementation to the sub-classes.

An interface provides just the method signatures without method bodies. Sub-classes should provide implementation for all the methods defined in an interface. Python doesn't support creation of interface through any separate keyword, you will have to define an interface using abstract class itself. If you create an abstract class which contains only abstract methods that acts as an interface in Python.

Abstraction in Python using abstract class

Let’s see an example of abstraction in Python using an abstract class. For declaring an Abstract class you need to import the abc module.

In the example we have an Abstract class User that has one concrete method display_user() and one abstract method process_fee().

from abc import ABC, abstractmethod

class User(ABC):
  def __init__(self, name, num_of_months):
    self.name = name
    self.num_of_months = num_of_months

  # concrete method
  def display_user(self):
    print('User %s subscribed for %d months' % (self.name, self.num_of_months))

  # abstract method
  @abstractmethod
  def process_fee(self):
    pass

There are two sub classes inheriting from User and implementing the abstract method process_fee().

class PlatinumUser(User):
  PLATINUM_PACKAGE = 2200

  def process_fee(self):
      return self.num_of_months * PlatinumUser.PLATINUM_PACKAGE


class GoldUser(User):
  Gold_PACKAGE = 1500

  def process_fee(self):
      return self.num_of_months * GoldUser.Gold_PACKAGE

As a user we just know that we have to call process_fee() method, we are abstracted from the actual implementation of the method which differs for different child classes of User.

obj = PlatinumUser('Mike Dallas', 8)
obj.display_user()
fee = obj.process_fee()
print('Fee is', fee)

obj = GoldUser('Goldie Hawn', 6)
obj.display_user()
fee = obj.process_fee()
print('Fee is', fee)

obj = PlatinumUser('Ashish Mishra', 10)
obj.display_user()
fee = obj.process_fee()
print('Fee is', fee)
Output
User Mike Dallas subscribed for 8 months
Fee is 17600
User Goldie Hawn subscribed for 6 months
Fee is 9000
User Ashish Mishra subscribed for 10 months
Fee is 22000

That's all for the topic Abstraction in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Sunday, January 10, 2021

Inheritance in Python With Examples

In this tutorial you’ll learn about OOPS concept inheritance and how to use inheritance in Python.

Inheritance concept

Inheritance allows us to create a class that acquires, all the properties and methods of another class.

The class whose members are inherited is called the Super class. Also known as parent class or base class.

The class that inherits from another class is called the Sub class. Also known as child class or derived class.

Python inheritance syntax

If there is a class called ParentClass defined as-

class ParentClass:
  body of parent class

Then a ChildClass that inherits from this ParentClass can be defined as-

class ChildClass(ParentClass):
  body of child class

Inheritance Python example

In the example there is a class called Person that acts as a base class and another class Employee that inherits from Person class.

class Person:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def display_person(self):
    print('In display_person method')
    print('Name:', self.name)
    print('Age:', self.age)

class Employee(Person):
  pass

e = Employee("Michael Weyman", 42)
e.display_person()
Output
In display_person method
Name: Michael Weyman
Age: 42

As you can see in Employee class just pass keyword is used to specify that it doesn’t add any property or method to a class. It just inherits all the properties and methods of the class it inherits from.

You can create an object of Employee class and initialize the ‘name’ and ‘age’ properties because Employee class inherits these properties from Person class. Same way you can also call the method display_person() method using the object of Employee class.

Constructor overriding and use of super with inheritance

When a class inherits another class in Python, by default constructor of the super class is also available to the child class. If you have extra fields in the child class which you need to initialize in the child class then you can override the constructor in the child class to initialize the fields there.

In most of the scenarios you’ll inherit from a base class and add properties and methods of its own in the child class as well. To initialize the properties of the child class you can add __init__() function in the child class too. In our Employee class let’s add two fields person_id and department and add a method display_employee() too.

class Employee(Person):
  def __init__(self, person_id, department, name, age):
    self.name = name
    self.age = age
    self.person_id = person_id
    self.department = department

  def display_employee(self):
    print('In display_employee method')
    print('Id:', self.person_id)
    print('Name:', self.name)
    print('Age:', self.age)
    print('Department:', self.department)

In the above class you can notice the redundancy of initializing the parent class’ fields in the constructor though there is a constructor in the parent class which is already doing that. Same way in the display_employee () method we have print statements to print name and age too though there is a method in Person class which is already doing that.

If you want to call super class constructor and methods from sub-class that can be done using super() function which helps in avoiding code redundancy as present in the above Employee class. Here is the modified Employee class with usage of super() function.

class Employee(Person):
  def __init__(self, person_id, department, name, age):
    # call constructor of super class
    super().__init__(name, age)
    self.person_id = person_id
    self.department = department

  def display_employee(self):
    # call method of super class
    super().display_person()
    print('In display_employee method')
    print('Id:', self.person_id)
    print('Department:', self.department)

e = Employee(1, "IT", "Michael Weyman", 42)
e.display_employee()
Output
In display_person method
Name: Michael Weyman
Age: 42
In display_employee method
Id: 1
Department: IT

Advantages of inheritance

  1. Inheritance helps in writing reusable code where you can use the existing functionality just by inheriting from an existing class.
  2. Inheritance helps in writing hierarchical code where you write more generalized code in the super class and then move on to inherit it and add more specific methods. For example you can have a Vehicle super class with more generic functionality like accelerate(), brake(), gear(). Then inherit it to create more specialized classes like Car, Bus, MotorCycle and further down to inherit from Car to create more specific classes like SUV, SportsCar.
  3. Also makes managing the code easy because you don’t put all the functionality in the same class you rather create several classes to create a hierarchical structure with code distributed among those classes.

That's all for the topic Inheritance in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Saturday, January 9, 2021

DelayQueue in Java With Examples

DelayQueue in Java is an implementation of BlockingQueue interface and is part of java.util.concurrent package. DelayQueue in Java is an unbounded queue that's where it differs from ArrayBlockingQueue which is a bounded queue.

Delayed interface

Java DelayQueue can store elements only of type Delayed. There is an interface Delayed in Java which defines the type for these elements.

Delayed interface is used to define type of objects that should be acted upon after a given delay.

public interface Delayed extends Comparable<Delayed> {
  long getDelay(TimeUnit unit);
}

The getDelay(TimeUnit unit) method returns the remaining delay associated with this object, in the given time unit.

Since Delayed interface also extends Comparable interface, an implementation of this interface must define a compareTo() method that provides an ordering consistent with its getDelay method.

DelayQueue expired elements

From DelayQueue in Java an element can only be taken when its delay has expired. Element is taken from the head of the queue which means the head of the queue is that Delayed element whose delay expired furthest in the past.

Expiration of an element in the queue occurs when an element's getDelay(TimeUnit.NANOSECONDS) method returns a value less than or equal to zero.

Blocking method like take() will wait until an element with an expired delay is available on this queue.

Features of the DelayQueue in Java

  1. DelayQueue stores element of type Delayed. Interface Delayed defines the type for these Delayed elements.
  2. Element from the DelayQueue can only be taken when its delay has expired.
  3. DelayQueue is a thread-safe implementation.
  4. DelayQueue in Java does not allow null element to be added.

Java DelayQueue Constructors

  • DelayQueue()- Creates a new DelayQueue that is initially empty.
  • DelayQueue(Collection<? extends E> c)- Creates a DelayQueue initially containing the elements of the given collection of Delayed instances.

DelayQueue Java example

Here is a producer-consumer example using DelayQueue. Since DelayQueue stores element of type Delayed so we need an implementation of Delayed interface too.

  private long expiryTime;
  DelayQElement(String queueElement, long delay){
    this.queueElement = queueElement;
    // Expirytime is current time + delay
    this.expiryTime = System.currentTimeMillis() + delay;
    System.out.println("Putting queueElement "  + queueElement + " expiry " + this.expiryTime);
  }
 
  @Override
  public long getDelay(TimeUnit unit) {
    long diff = expiryTime - System.currentTimeMillis();
    return unit.convert(diff, TimeUnit.MILLISECONDS);
  }
 
  @Override
  public int compareTo(Delayed o) {
  if(this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)){ 
    return -1; 
  } 
  if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)){
    return 1;
  }
  return 0;     
  }
  public String toString(){
    return queueElement + " Expiry Time= " + expiryTime;
  } 
}
Producer-Consumer using DelayQueue
public class DQDemo {
  public static void main(String[] args) {
    // delay of 3 seconds
    final long delay = 3000;
    BlockingQueue<DelayQElement> delayQ = new DelayQueue<DelayQElement>();
    // Producer thread
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          delayQ.put(new DelayQElement("Element"+i, delay));
          Thread.sleep(50);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }).start();
        
    // Consumer thread
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          System.out.println(" Consumer got - " + delayQ.take().toString());
          Thread.sleep(100);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }
    }).start();
  }
}
Output
Putting queueElement Element0expiry 1541830388935
Putting queueElement Element1expiry 1541830388998
Putting queueElement Element2expiry 1541830389060
Putting queueElement Element3expiry 1541830389123
Putting queueElement Element4expiry 1541830389185
 Consumer got - Element0 Expiry Time= 1541830388935
 Consumer got - Element1 Expiry Time= 1541830388998
 Consumer got - Element2 Expiry Time= 1541830389060
 Consumer got - Element3 Expiry Time= 1541830389123
 Consumer got - Element4 Expiry Time= 1541830389185

As you can see the elements are taken from the queue after the element expired.

DelayQueue class methods

Here is a list of some of the methods of the DelayQueue class in Java.
  1. add(E e)- Inserts the specified element into this delay queue.
  2. clear()- Atomically removes all of the elements from this delay queue.
  3. offer(E e)- Inserts the specified element into this delay queue.
  4. peek()- Retrieves, but does not remove, the head of this queue, or returns null if this queue is empty.
  5. poll()- Retrieves and removes the head of this queue, or returns null if this queue has no elements with an expired delay.
  6. poll(long timeout, TimeUnit unit)- Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue, or the specified wait time expires.
  7. put(E e)- Inserts the specified element into this delay queue.
  8. remove(Object o)- Removes a single instance of the specified element from this queue, if it is present, whether or not it has expired.
  9. take()- Retrieves and removes the head of this queue, waiting if necessary until an element with an expired delay is available on this queue.

That's all for the topic DelayQueue in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Friday, January 8, 2021

SynchronousQueue in Java With Examples

SynchronousQueue in Java is an implementation of BlockingQueue interface and is part of java.util.concurrent package. SynchronousQueue in Java is different from other BlockingQueue implementations like ArrayBlockingQueue and PriorityBlockingQueue because a synchronous queue does not have any internal capacity, not even a capacity of one. So, each insert operation in SynchronousQueue must wait for a corresponding remove operation by another thread, and vice versa.

That is why it is named SynchronousQueue as the hand-off of the element happens synchronously rather than inserting the data that can be retrieved asynchronously.

Features of SynchronousQueue in Java

  1. SynchronousQueue doesn’t have any internal capacity, not even one.
  2. Since there is no capacity each insert operation must wait for a corresponding remove operation by another thread. For example if you insert an element to synchronous queue using put() method the method is blocked until another thread receives that element. Same way if you are trying to retrieve an element from the synchronous queue and there is no element in the queue method waits for another thread to insert it.
  3. You cannot peek at a synchronous queue because an element is only present when you try to remove it. So the peek() method always returns null.
  4. SynchronousQueue can't be iterated as there is nothing to iterate. So the iterator() and spliterator() methods return an empty iterator or spliterator respectively.
  5. SynchronousQueue in Java, just like other BlockingQueue implementations, does not permit null elements. It throws NullPointerException on attempts to add, put or offer a null.

Java SynchronousQueue constructors

  • SynchronousQueue()- Creates a SynchronousQueue with nonfair access policy.
  • SynchronousQueue(boolean fair)- Creates a SynchronousQueue with the specified fairness policy. A SynchronousQueue constructed with fairness set to true grants threads access in FIFO order.

SynchronousQueue Java example

BlockingQueue implementations are designed to be used primarily for producer-consumer queues so let's see an example of producer-consumer using SynchronousQueue. In the example two threads are created one a producer thread and another a consumer thread.

In the consumer thread delay of 3 seconds is introduced using the sleep() method before taking the element out of the synchronous queue but the put() method waits until the elements is retrieved rather than trying to add another element.

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;

public class SychroQ {
  public static void main(String[] args) {
    BlockingQueue<Integer> bQueue = new SynchronousQueue<>();
    // Producer 
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          System.out.println("Added to queue-" + i);
          bQueue.put(i);
          Thread.sleep(200);                                 
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        }
    }).start();
        
    // Consumer
    new Thread(()->{
      for(int i = 0; i < 5; i++){
        try {
          Thread.sleep(3000);
          System.out.println("Consumer retrieved- " + bQueue.take());                    
          
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
      }
    }).start();
  }
}
Output
Added to queue-0
Consumer retrieved- 0
Added to queue-1
Consumer retrieved- 1
Added to queue-2
Consumer retrieved- 2
Added to queue-3
Consumer retrieved- 3
Added to queue-4
Consumer retrieved- 4

That's all for the topic SynchronousQueue in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Synchronized Vs ReentrantLock in Java

The traditional way of acquiring a mutual exclusion lock in Java is to use synchronized keyword but Java 5 added new lock implementations like ReentrantLock and ReentrantReadWriteLock which provide extended locking operations capabilities. In this post we'll see the difference between synchronized and ReentrantLock in Java.

ReentrantLock Vs synchronized in Java

1- When you use synchronized keyword the implicit lock associated with the object is acquired automatically as soon as the synchronized method or block is entered and the lock is released automatically as soon as the synchronized method or block ends.

With ReentrantLock the acquisition and releasing the lock is done using the methods lock() and unlock().

2- The usage of synchronized is more rigid. All lock acquisition and release should occur in a block-structured way- when multiple locks are acquired they must be released in the opposite order, not doing that may result in a deadlock. All locks must be released in the same lexical scope in which they were acquired.

ReentrantLock usage is more flexible. It allows a lock to be acquired and released in different scopes, it also allows multiple locks to be acquired and released in any order.

3- The flexibility provided by ReentrantLock in terms of ordering of locks and the use of methods lock() and unlock() to acquire and release the lock puts the responsibility on user of following the convention as shown below when using ReentrantLock.

 Lock l = new ReentrantLock();
 l.lock();
 try {
   // access the resource protected by this lock
 } finally {
   l.unlock();
 }

lock should be acquired before entering a try block and lock should be released in a finally block.

While using synchronized to guard the critical section there is no such convention as acquiring and releasing of the lock is done implicitly.

4- ReentrantLock provides additional functionality over the use of synchronized methods and statements.

  • Provides a non-blocking attempt to acquire a lock using tryLock() method that acquires the lock only if it is not held by another thread at the time of invocation.
  • Provides a feature to acquire the lock that can be interrupted using lockInterruptibly() method that acquires the lock unless the current thread is interrupted.
  • Provides a feature to acquire the lock that can timeout using the tryLock(long timeout, TimeUnit unit) method that acquires the lock if it is not held by another thread within the given waiting time and the current thread has not been interrupted.

5- ReentrantLock also provides an option for fairness which is not there with synchronized methods and statements. If using synchronized keyword any of the waiting thread can acquire the lock which may lead to thread starvation.

ReentrantLock class has a constructor which takes boolean value as an argument.

ReentrantLock(boolean fair)

when boolean value is passed as true this lock should use a fair ordering policy. Note that fair locks favors those threads that have been waiting the longest.

That's all for the topic Synchronized Vs ReentrantLock in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

ReentrantReadWriteLock in Java With Examples

In this post we’ll see the usage of java.util.concurrent.locks.ReadWriteLock interface and its implementing class ReentrantReadWriteLock in Java with examples.

ReadWriteLock in Java Concurrency

ReadWriteLock as the name itself suggests has a pair of associated locks-

  • One for read-only operations
  • One for writing operations

The usage of read lock and write lock is as follows-

  • The read lock may be held simultaneously by multiple reader threads as long as there are no threads with write lock access.
  • The write lock is exclusive. Which means no thread has acquired either read lock or write lock when the thread obtains a write lock.

Benefits of ReadWriteLock

The traditional way of synchronizing the threads requires a mutually exclusive lock. Even if thread is just reading the shared resource (not modifying it) lock is still mutually exclusive i.e. no other thread can enter the critical section while the resource is locked.

A read-write lock allows for a greater level of concurrency in accessing shared data than that permitted by a mutual exclusion lock. It works on a principle that while only a single thread at a time (a writer thread) can modify the shared data, in many cases any number of threads can concurrently read the data (hence reader threads) which may help in increasing performance in a multi-threaded environment.

ReentrantReadWriteLock in Java Concurrency

ReentrantReadWriteLock class in Java is an implementing class of the ReadWriteLock interface. It is used in the following way.

To create a ReentrantReadWriteLock-

ReadWriteLock rwl = new ReentrantReadWriteLock();

For getting read lock-

Lock readLock = rwl.readLock();

For getting write lock-

Lock writeLock = rwl.writeLock();

Here note that ReadLock and WriteLock are the static nested classes with in the ReentrantReadWriteLock class-

  • ReentrantReadWriteLock.ReadLock- The lock returned by method ReadWriteLock.readLock().
  • ReentrantReadWriteLock.WriteLock- The lock returned by method ReadWriteLock.writeLock().

Locking and unlocking using read lock and write lock is done as follows.

Read lock-
rwl.readLock().lock();
try {
  ..
  ..
}finally{
  rwl.readLock().unlock();
}
Write Lock-
rwl.writeLock().lock();
try {
  ..
  ..
}finally{
  rwl.writeLock().lock();
}

As you can see ReentrantReadWriteLock follows the same convention as followed with ReentrantLock in Java where call to lock() method is placed before try block and then followed with a try-finally or try-catch-finally block and uses finally block to call unlock() method.

That way unlock() method is called only if the lock is actually acquired and it is also ensured that the unlock() method is called if there is any error after the lock is acquired.

Java ReentrantReadWriteLock constructors

  • ReentrantReadWriteLock()- Creates a new ReentrantReadWriteLock with default (nonfair) ordering properties.
  • ReentrantReadWriteLock(boolean fair)- Creates a new ReentrantReadWriteLock with the given fairness policy.

ReentrantReadWriteLock example in Java

In the example we’ll have a HashMap that is used by multiple threads. While putting element in the HashMap a write lock is acquired as it is a modifying operation. In case of get method a read lock is used so several threads can get values from the HashMap. Then two write threads and three read threads are started to put and get values from the HashMap.

public class RWLDemo {
  private final Map<String, String> numberMap = new HashMap<String, String>();
  private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
  // get method with read lock
  public String get(String key) {
    System.out.println("Waiting to acquire lock in get method...");
    rwl.readLock().lock();
    System.out.println("Acquired read lock in get method");
    try { 
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
       return numberMap.get(key); 
    }
    finally { 
      System.out.println("releasing read lock in get method ");
      rwl.readLock().unlock(); 
    }
  }
   
  // Put method with write lock
  public String put(String key, String value) {
    System.out.println("Waiting to acquire lock in put method...");
    rwl.writeLock().lock();
    System.out.println("Acquired write lock in put method");
    try { 
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
      return numberMap.put(key, value); 
    }
    finally {
      System.out.println("Releasing write lock in put method ");
      rwl.writeLock().unlock(); 		  
    }
  }
   
  public static void main(String[] args) {
    RWLDemo rwlDemo = new RWLDemo();
    // To put some initial values in the Map
    rwlDemo.initialValueInMap();
    // Starting Three read threads and two write threads
    Thread wThread1 = new Thread(new WriterThread(rwlDemo, "3", "Three"));
    Thread rThread1 = new Thread(new ReadThread(rwlDemo, "1"));        
    Thread rThread2 = new Thread(new ReadThread(rwlDemo, "1"));
    Thread wThread2 = new Thread(new WriterThread(rwlDemo, "4", "Four"));
    Thread rThread3 = new Thread(new ReadThread(rwlDemo, "2"));

    wThread1.start();
    rThread1.start();
    rThread2.start();
    rThread3.start();
    wThread2.start();
  }

  private void initialValueInMap(){
    // Putting some values in the map
    numberMap.put("1", "One");
    numberMap.put("2", "Two");
  }
}

class ReadThread implements Runnable {
  RWLDemo rwDemo;
  String key;
  ReadThread(RWLDemo rwDemo, String key){
    this.rwDemo = rwDemo;
    this.key = key;
  }
  public void run() {
    System.out.println("Value - " + rwDemo.get(key));
  }
}

class WriterThread implements Runnable {
  RWLDemo rwDemo;
  String key;
  String value;
  WriterThread(RWLDemo rwDemo, String key, String value){
    this.rwDemo = rwDemo;
    this.key = key;
    this.value = value;
  }
  public void run() {
    rwDemo.put(key, value);
  }
}
Output
Waiting to acquire lock in put method...
Waiting to acquire lock in put method...
Waiting to acquire lock in get method...
Waiting to acquire lock in get method...
Acquired read lock in get method
Waiting to acquire lock in get method...
Acquired read lock in get method
releasing read lock in get method 
Value - Two
releasing read lock in get method 
Acquired write lock in put method
Value - One
Releasing write lock in put method 
Acquired read lock in get method
releasing read lock in get method 
Acquired write lock in put method
Value - One
Releasing write lock in put method 

You can see from the output initially two read threads are acquired both can access the locked section. Once read locks are released then only write lock is acquired as write lock has to get exclusive access. There is another read lock that waits for the write lock to release the write lock then only read lock is acquired.

ReentrantReadWriteLock Properties

  1. There is no reader or writer preference ordering for lock access. However, it does support an optional fairness policy.
  2. When ReentrantReadWriteLock is constructed as non-fair, which is the default, the order of entry to the read and write lock is unspecified.
  3. When ReentrantReadWriteLock is constructed as fair, threads contend for entry using an approximately arrival-order policy. When the currently held lock is released, either the longest-waiting single writer thread will be assigned the write lock, or if there is a group of reader threads waiting longer than all waiting writer threads, that group will be assigned the read lock.
  4. Both read and write lock can reacquire read or write locks in the style of a ReentrantLock. See example here.
  5. Reentrancy also allows downgrading from the write lock to a read lock, by acquiring the write lock, then the read lock and then releasing the write lock.
  6. Upgrading from a read lock to the write lock is not possible.
Reference: https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

That's all for the topic ReentrantReadWriteLock in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Thursday, January 7, 2021

CountDownLatch Vs CyclicBarrier in Java

Both CountDownLatch and CyclicBarrier are synchronization aids in Java concurrency that facilitate communication among threads. Both of these synchronization aids create a latch or a barrier to make threads wait until a condition is satisfied and then only the threads can make further progress. In this post we’ll see the difference between CountDownLatch and CyclicBarrier in Java.

CountDownLatch and CyclicBarrier

  • CyclicBarrier- A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
  • CountDownLatch- A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

CountDownLatch Vs CyclicBarrier in Java

1- Initialization:

A CountDownLatch is initialized with a given count where count denotes the number of times countDown() must be invoked before threads can pass through await().

A CyclicBarrier is initialized with a given number of parties, where parties denotes the number of threads and the CyclicBarrier trips when the given number of parties (threads) are waiting upon it.

This initialization makes CountDownLatch more versatile synchronization tool-

  • A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown().
  • A CountDownLatch initialized to N can be used to make one thread wait until N threads have completed some action, or some action has been completed N times.

With CyclicBarrier you specify the number of threads that are waiting upon it which means if you have a CyclicBarrier initialized to 3 then 3 threads should invoke await() on this barrier to trip the barrier. That makes CyclicBarrier more useful for scenario involving a fixed sized party of threads that must occasionally wait for each other.

2- Reusability:

One of the main difference between CountDownLatch and CyclicBarrier is that CountDownLatch can’t be reused. Once the count has reached zero for the CountDownLatch instance the count cannot be reset.

CyclicBarrier can be re-used after the waiting threads are released.

3- Optional Runnable:

CyclicBarrier class has a constructor where a Runnable barrierAction can be provided.

public CyclicBarrier(int parties, Runnable barrierAction)

The given barrier action is executed when the barrier is tripped, performed by the last thread entering the barrier.

So there is an option to execute a separate Runnable action with CyclicBarrier.

CountDownLatch class in Java doesn't have any such constructor to specify a runnable action.

4- Exception:

The CyclicBarrier uses an all-or-none breakage model for failed synchronization attempts: If a thread leaves a barrier point prematurely because of interruption, failure, or timeout, all other threads waiting at that barrier point will also leave abnormally via BrokenBarrierException (or InterruptedException if they too were interrupted at about the same time).

  • If any thread is interrupted while waiting, then all other waiting threads will throw BrokenBarrierException and the barrier is placed in the broken state.
  • If the barrier is reset() while any thread is waiting, or if the barrier is broken when await is invoked, or while any thread is waiting, then BrokenBarrierException is thrown.

With CountDownLatch if a current thread is interrupted while waiting then InterruptedException is thrown.

That's all for the topic CountDownLatch Vs CyclicBarrier in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

Wednesday, January 6, 2021

Phaser in Java With Examples

Many synchronization aid were added as the part of java.util.concurrent package in Java 5 like Semaphore, Exchanger. One more synchronization aid added as part of Java concurrency is Phaser which was added in Java 7.

Phaser in Java concurrency

Phaser in Java is also a synchronization barrier like CountDownLatch and CyclicBarrier where threads need to wait at a barrier until all the threads have reached the barrier that is when barrier is tripped. Phaser offers more flexibility by synchronizing threads over multiple phases. In each phase threads can be dynamically registered and unregistered.

Some important points about Phaser in Java are as follows-
  • Using Phaser you can synchronize over multiple phases reusing the same phaser instance.
  • Once all the threads register for a phase arrive at a barrier that phase is considered complete and the next phase starts.
  • You can use Phaser to synchronize a single phase too but it is more useful when used to synchronize multiple phases.

Java Phaser constructors

There are four constructors in the Phaser class.

  • Phaser()- Creates a new phaser with no initially registered parties, no parent, and initial phase number 0.
  • Phaser(int parties)- Creates a new phaser with the given number of registered unarrived parties, no parent, and initial phase number 0.
  • Phaser(Phaser parent, int parties)- Creates a new phaser with the given parent and number of registered unarrived parties.
  • Phaser(Phaser parent)- Creates a new phaser with the given parent and no initially registered parties.

How Phaser works in Java

  1. First thing is to create an instance of Phaser.
  2. Register parties with phaser by calling the register() method, you can also use the constructor where number of parties is passed as an argument.
  3. To signal that the party has arrived at a phase one of the arrive() method has to be called. Once all the registered parties have arrived at a phase that phase is considered complete.
  4. Each generation of a phaser has an associated phase number. The phase number starts at zero, and advances when all parties arrive at the phaser.

Phaser example in Java

Here is an example showing Phaser in action. There are two runnable tasks which will be executed as two separate phases. First runnable task (FirstTask) is executed by three threads, for that you can see 3 parties are registered using bulkRegister() method.

For second runnable task (SecondTask) register method is called with in the runnable class.

public class PhaserDemo {
  public static void main(String[] args) {
    Phaser ph = new Phaser(1);
    // registering 3 parties in bulk
    ph.bulkRegister(3);
    System.out.println("Phase in Main " + ph.getPhase() + " started");
    // starting 3 threads
    for(int i = 0; i < 3; i++) {      	
      new Thread(new FirstTask("Thread-"+i, ph)).start();
    }
    int curPhase = ph.getPhase();
    // This is to make main thread wait
    ph.arriveAndAwaitAdvance();
    System.out.println("Phase in Main " + curPhase + " completed");

    for(int i = 0; i < 2; i++) {     	
      new Thread(new SecondTask("Thread-"+i, ph)).start();
    }
    ph.arriveAndAwaitAdvance();
    System.out.println("Phase in Main-2 " + ph.getPhase() + " completed");
    // deregistering the main thread
    ph.arriveAndDeregister();
  }
}

class FirstTask implements Runnable {
  private String threadName;
  private Phaser ph;

  FirstTask(String threadName, Phaser ph){
    this.threadName = threadName;
    this.ph = ph;       
  }
  @Override
  public void run() {
    System.out.println("In First Task.. " + threadName);
    // parties will wait here
    ph.arriveAndAwaitAdvance();
    
    System.out.println("Deregistering, Phase- "+ ph.getPhase() + " Completed");
    ph.arriveAndDeregister();
  }
}

class SecondTask implements Runnable {
  private String threadName;
  private Phaser ph;
    
  SecondTask(String threadName, Phaser ph){
    this.threadName = threadName;
    this.ph = ph;
    ph.register();
  }
    
  @Override
  public void run() {
    System.out.println("In SecondTask.. " + threadName);
    ph.arriveAndAwaitAdvance();
    System.out.println("In SecondTask.. Phase-" + ph.getPhase() + " completed" + threadName);
    ph.arriveAndDeregister();
  }
}
Output
Phase in Main 0 started
In First Task.. Thread-0
In First Task.. Thread-1
In First Task.. Thread-2
Deregistering, Phase- 1 Completed
Phase in Main 0 completed
Deregistering, Phase- 1 Completed
Deregistering, Phase- 1 Completed
In SecondTask.. Thread-0
In SecondTask.. Thread-1
Phase in Main-2 2 completed
In SecondTask.. Phase-2 completedThread-0
In SecondTask.. Phase-2 completedThread-1

Methods in Phaser class

Some of the important methods of the Phaser class in Java are listed below-

  • arrive()- Arrives at this phaser, without waiting for others to arrive.
  • arriveAndAwaitAdvance()- Arrives at this phaser and awaits others.
  • arriveAndDeregister()- Arrives at this phaser and deregisters from it without waiting for others to arrive.
  • awaitAdvance(int phase)- Awaits the phase of this phaser to advance from the given phase value, returning immediately if the current phase is not equal to the given phase value or this phaser is terminated.
  • bulkRegister(int parties)- Adds the given number of new unarrived parties to this phaser.
  • getArrivedParties()- Returns the number of registered parties that have arrived at the current phase of this phaser.
  • getParent()- Returns the parent of this phaser, or null if none.
  • getPhase()- Returns the current phase number.
  • isTerminated()- Returns true if this phaser has been terminated.
  • onAdvance(int phase, int registeredParties)- Overridable method to perform an action upon impending phase advance, and to control termination.
  • register()- Adds a new unarrived party to this phaser.

That's all for the topic Phaser in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Exchanger in Java With Examples

Many synchronization aid were added as the part of java.util.concurrent package in Java 5 like CyclicBarrier, Semaphore. One more synchronization aid added as part of Java concurrency is Exchanger. In this post we’ll see what is Exchanger in Java, how does it work and an example of Exchanger.

Exchanger in Java Concurrency

Exchanger in Java is a synchronization aid that helps in exchanging the data between two threads. When two threads call exchange() method the objects supplied by these two threads are exchanged.

Exchanger in Java

Exchanger can be used in a Producer-Consumer scenario where a producer thread produces a buffer which can be exchanged with an empty buffer from consumer thread.

Java Exchanger class constructor

Exchanger class has only one constructor.

  • Exchanger()- Creates a new Exchanger.

Methods in Exchanger class

Exchanger class in Java has only one method exchange() which has two overloaded forms.

  • exchange(V x)- Waits for another thread to arrive at this exchange point (unless the current thread is interrupted), and then transfers the given object to it, receiving its object in return.
  • exchange(V x, long timeout, TimeUnit unit)- Waits for another thread to arrive at this exchange point (unless the current thread is interrupted or the specified waiting time elapses), and then transfers the given object to it, receiving its object in return.

Java Exchanger example

Here is an example of producer consumer threads where threads use Exchanger to exchange data. The data which is exchanged is of type DataBuffer.

DataBuffer.java
import java.util.ArrayList;
import java.util.List;

public class DataBuffer {
  private List data = new ArrayList<>();

  public String getData() {
    return data.remove(0);
  }
  public void addToBuffer(String str) {
    data.add(str);
  }
  public boolean isFull() {
    if(data.size() == 1) 
      return true;
    return false;
  }
}
public class ExchangerDemo {
  public static void main(String[] args) {
    Exchanger ex = new Exchanger();
    // Starting two threads
    new Thread(new Producer(ex)).start();
    new Thread(new Consumer(ex)).start();
  }
}
// Producer class
class Producer implements Runnable {
  Exchanger ex;
  DataBuffer producerBuffer;
  Producer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer producerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){
      producerBuffer.addToBuffer("Producer" + i);
      try {
        if (producerBuffer.isFull()) {
          // exchange
          producerBuffer = ex.exchange(producerBuffer);
        }
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}
// Consumer class
class Consumer implements Runnable {
  Exchanger ex;
  DataBuffer consumerBuffer;
  Consumer(Exchanger ex){
    this.ex = ex;
  }
  @Override
  public void run() {
    DataBuffer consumerBuffer = new DataBuffer();
    for(int i = 0; i < 3; i ++){        	
      try {  
        System.out.println("waiting...");
        consumerBuffer = ex.exchange(consumerBuffer);
        System.out.println("Received- " + consumerBuffer.getData());
      } catch (InterruptedException e) {
        System.out.println(e);
      }
    }       
  }   
}
Output
waiting...
Received- Producer0
waiting...
Received- Producer1
waiting...
Received- Producer2

That's all for the topic Exchanger in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Semaphore in Java With Examples

Semaphore is a synchronization aid that can be used for inter-communication among threads or to restrict access to resource. An implementation of Semaphore in Java is available for out of box use and it is part of java.util.concurrent package.

Counting semaphore

The implementation of semaphore readily available in the Java concurrency package is a counting semaphore.

Conceptually, a semaphore maintains a set of permits. When a semaphore is created it is created with a given number of permits. The working of semaphore in Java can be explained using the following steps-

  1. A thread that wants to access a shared resource tries to acquire a permit using the acquire() method.
  2. If permit is available or in other words if semaphore count is greater than zero then the thread acquires a permit otherwise thread is blocked.
  3. With every successful acquisition of the permit the count is also decremented. If count becomes zero then no permit can be given.
  4. When the thread is done with the shared resource it can release the acquired permit using the release() method. This increments the semaphore's count.
  5. Any blocking thread waiting to acquire a permit can get a permit once count is more than zero.

Java semaphore constructors

  • Semaphore(int permits)- Creates a Semaphore with the given number of permits and nonfair fairness setting.
  • Semaphore(int permits, boolean fair)- Creates a Semaphore with the given number of permits and the given fairness setting.

Semaphore example in Java

Let’s say there is a method that is computation heavy and you want to restrict access to this method to 2 threads at any given time. In this scenario you can use Semaphore created with 2 permits.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemaphoreDemo {
  public static void main(String[] args) {
    // Semaphore with 2 permits
    Semaphore s = new Semaphore(2);
    ExecutorService ex = Executors.newFixedThreadPool(4);
    // Executing 6 times with a pool of 4 threads
    for(int i = 0; i < 6; i++) {
      ex.execute(new HeavyDuty(s));
    }
    ex.shutdown();
  }
}

class HeavyDuty implements Runnable{
  private Semaphore s;
  HeavyDuty(Semaphore s){
    this.s = s;
  }
  @Override
  public void run() {
    try {
      s.acquire();
      System.out.println("Permit ACQUIRED by " + Thread.currentThread().getName());
      doProcessing();	
      System.out.println("Permit released by " + Thread.currentThread().getName());
      s.release();		
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }				
  }
  private void doProcessing() throws InterruptedException{
    System.out.println("doing heavy computation processing ");
    Thread.sleep(5000);
  }
}
Output
Permit ACQUIRED by pool-1-thread-1
doing heavy computation processing 
Permit ACQUIRED by pool-1-thread-2
doing heavy computation processing 
Permit released by pool-1-thread-1
Permit ACQUIRED by pool-1-thread-4
doing heavy computation processing 
Permit released by pool-1-thread-2
Permit ACQUIRED by pool-1-thread-3
doing heavy computation processing 
Permit released by pool-1-thread-4
Permit ACQUIRED by pool-1-thread-1
doing heavy computation processing 
Permit released by pool-1-thread-3
Permit ACQUIRED by pool-1-thread-2
doing heavy computation processing 
Permit released by pool-1-thread-1
Permit released by pool-1-thread-2

As you can see at any given time permits are acquired by 2 threads.

Binary Semaphore

A semaphore in Java created with only one permit can serve as a mutual exclusion lock. This is more commonly known as a binary semaphore, because it only has two states: one permit available, or zero permits available.

Binary Semaphore example in Java

Here is a simple binary semaphore example where a shared counter is used among multiple threads. Binary semaphore let only one thread access the shared resource at any given time.

public class SemaphoreDemo {
  public static void main(String[] args) {
    // Semaphore with 1 permit
    Semaphore s = new Semaphore(1);
    SharedCounter counter = new SharedCounter(s);
    for(int i = 0; i < 6; i++) {
      new Thread(counter).start();
    }
  }
}

class SharedCounter implements Runnable{
  private int c = 0;
  private Semaphore s;
  SharedCounter(Semaphore s){
   this.s = s;
  }
  @Override
  public void run() {
    try {
      s.acquire();
      incrCounter();
      s.release();	
    }catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  // incrementing the value
  public void incrCounter()  throws InterruptedException{
    Thread.sleep(10);
    System.out.println("Value for Thread After increment - " + 
        Thread.currentThread().getName() + " " + ++c);
  }
}
Output
Value for Thread After increment - Thread-0 1
Value for Thread After increment - Thread-1 2
Value for Thread After increment - Thread-2 3
Value for Thread After increment - Thread-3 4
Value for Thread After increment - Thread-4 5
Value for Thread After increment - Thread-5 6

To see how threads can interfere you can comment the acquire and release methods with in the run() method.

public void run() {
  try {
    //s.acquire();
    incrCounter();
    //s.release();	
  }catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

Running after commenting gives the following output for one run where same count is displayed for 2 threads.

Value for Thread After increment - Thread-4 1
Value for Thread After increment - Thread-2 2
Value for Thread After increment - Thread-0 3
Value for Thread After increment - Thread-5 4
Value for Thread After increment - Thread-3 1
Value for Thread After increment - Thread-1 2

Methods in Java Semaphore class

Some of the important methods in Semaphore class in Java are as follows-

  1. acquire()- Acquires a permit from this semaphore, blocking until one is available, or the thread is interrupted.
  2. acquire(int permits)- Acquires the given number of permits from this semaphore, blocking until all are available, or the thread is interrupted.
  3. availablePermits()- Returns the current number of permits available in this semaphore.
  4. drainPermits()- Acquires and returns all permits that are immediately available, or if negative permits are available, releases them.
  5. getQueuedThreads()- Returns a collection containing threads that may be waiting to acquire.
  6. isFair()- Returns true if this semaphore has fairness set true.
  7. release()- Releases a permit, returning it to the semaphore.
  8. tryAcquire()- Acquires a permit from this semaphore, only if one is available at the time of invocation.
  9. tryAcquire(int permits)- Acquires the given number of permits from this semaphore, only if all are available at the time of invocation.

That's all for the topic Semaphore in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like