Java @ Desk

Java @ Desk

Breaking

Monday, December 24, 2018

Semaphore In Java With Real Time Example

8:41 PM 0
Semaphore In Java With Real Time Example

Semaphore has been introduced in Java 5 to provide access to shared resources in an effective manner. Semaphore controls the number of threads to access shared resources. Semaphore is initialized with the integer count where only that many threads get access to shared resources.

Consider a real time example of Washroom access at a Railway Station that has only 2 washroom. When both the washroom gets filled, people outside need to wait to get them empty. In this case,
Semaphore is initialized with count as 2. Since the entry to washrooms must be allowed in a fair manner, Semaphore is initialized with fair - true. This make sure clients waiting outside must get fair chance i.e. first one in the queue must get first entry as soon as one of the washroom is available.
Semaphore is initialized with count 2. If 1 person enters the first washroom, Semaphore count is reduced to 1 by giving a call to semaphore.acquire(). When second person enters 2nd washroom, Semaphore is reduced to 0 by calling semaphore.acquire().
Now all the clients are waiting for atleast one washroom to become available. As soon as one of the washroom gets free, Semaphore is incremented to 1 by calling semaphore.release(). As soon as count becomes 1, the client waiting first get access to washroom, and so Semaphore count becomes 0 again and all clients wait in the queue. As soon as 2nd goes empty, Semaphore again increase to 1 by calling semaphore.release() and another client gets a chance.
There is a case when both the washrooms goes empty, in that case, Semaphore count is again incremented to 2.

Here is a realtime implementation of above -
SemaphoreClient.java - This is a client file that initializes Semaphore to 2 and initialize 5 clients to access washroom
package com.learning.semaphore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

public class SemaphoreClient {
    public static void main(String args[]) {

        Semaphore washRoomSemaphore = new Semaphore(2, true);

        List<ClientThread> clientThreads = new ArrayList<ClientThread>();

        for(int i = 1; i <= 5; i++) {
            ClientThread clientThread = new ClientThread();
            clientThread.setWashRoomSemaphore(washRoomSemaphore);
            clientThread.setClientNumber(i);
            clientThreads.add(clientThread);
        }

        for(ClientThread clientThread : clientThreads) {
            Thread thread = new Thread(clientThread);
            thread.start();
        }
    }
}


ClientThread.java - This is a client thread that acquire and releases Semaphore in order to access Washroom
package com.learning.semaphore;

import java.util.concurrent.Semaphore;

public class ClientThread implements Runnable {
    public void run() {
        System.out.println("Client - " + this.clientNumber + " waiting for Washroom access");
        try {
            this.washRoomSemaphore.acquire();
            System.out.println("Client - " + this.clientNumber + " got access to Washroom");
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        } finally {
            this.washRoomSemaphore.release();
            System.out.println("Client - " + this.clientNumber + " released Washroom");
        }
    }

    private Semaphore washRoomSemaphore;

    private int clientNumber;

    public Semaphore getWashRoomSemaphore() {
        return washRoomSemaphore;
    }

    public void setWashRoomSemaphore(Semaphore washRoomSemaphore) {
        this.washRoomSemaphore = washRoomSemaphore;
    }

    public int getClientNumber() {
        return clientNumber;
    }

    public void setClientNumber(int clientNumber) {
        this.clientNumber = clientNumber;
    }
}


Output -
Client - 1 waiting for Washroom access
Client - 1 got access to Washroom
Client - 2 waiting for Washroom access
Client - 2 got access to Washroom
Client - 3 waiting for Washroom access
Client - 4 waiting for Washroom access
Client - 5 waiting for Washroom access
Client - 3 got access to Washroom
Client - 4 got access to Washroom
Client - 1 released Washroom
Client - 2 released Washroom
Client - 4 released Washroom
Client - 5 got access to Washroom
Client - 3 released Washroom
Client - 5 released Washroom


Its visible as soon as 2 threads got access to Washroom, Semaphore is reduced to 0 and other clients enter in wait state.

Saturday, December 15, 2018

CyclicBarrier in Java with Real Time Example

10:57 PM 0
CyclicBarrier in Java with Real Time Example

CyclicBarrier is a thread syncronization mechanism in which all the threads are requested to wait at a certain point, before all of them move forward. The specific point is called a barrier and threads enter into a wait state at barrier point until all working threads reaches at that point. Once all threads reaches barrier point, they are allowed to continue.

The importance of a Cyclic Barrier is that it is cyclic i.e. once all the threads reaches barrier point and resumes their individual jobs, CyclicBarrier is allowed to reset.

Here is an example of a Cricket Match. Before a bowler is allowed to bowl first delivery, it waits for 2 umpires to reach their specific positions and all 10 fielders at their respective fielding positions. Until and unless 2 umpires and 11 fielders reaches at their respective positions, no thread can move forward. For example, even if 2 umpires and 10 fielders reach their points, they still need to wait for 11th player to reach to his position. Once 11th player reaches his position and calls await() method, bowler is allowed to bowl.

Here is a real time implementation of CyclicBarrier

CyclicBarrierCricket.java - This is a main class that initializes CyclicBarrier. It initializes threads for 11 Players and 2 Umpires and then calls the await method(). As soon as both the umpires and 11 players calls await(), this thread moves forward.
package com.cyclicbarrier.learning;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierCricket {

 public static void main(String args[]) {
  CyclicBarrier barrier = new CyclicBarrier(14);
  System.out.println("Match about to Start");

  System.out.println("Initializing Umpires");

  for (int i = 1; i <= 2; i++) {
   CyclicBarrierUmpire barrierUmpire = new CyclicBarrierUmpire();
   barrierUmpire.setUmpireNumber(i);
   barrierUmpire.setCyclicBarrier(barrier);
   Thread thread = new Thread(barrierUmpire);
   thread.start();
  }

  System.out.println("Umpires Thread Started");

  System.out.println("Initializing Players");

  for (int i = 1; i <= 11; i++) {
   CyclicBarrierPlayers cyclicBarrierPlayers = new CyclicBarrierPlayers();
   cyclicBarrierPlayers.setPlayerNumber(i);
   cyclicBarrierPlayers.setCyclicBarrier(barrier);
   Thread thread = new Thread(cyclicBarrierPlayers);
   thread.start();
  }

  System.out.println("Players Thread Started");
  
        try {
   barrier.await();
  } catch (InterruptedException | BrokenBarrierException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

        System.out.println("Players and Umpires all set at their respective Positions. Lets start a Game");
 }

}


CyclicBarrierUmpire.java - This is a Java thread to initialize both the umpires. Both the umpires calls the await() method to notify that we are all set and waiting for rest of the players to move to the position.
package com.cyclicbarrier.learning;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierUmpire implements Runnable {

    private CyclicBarrier cyclicBarrier;
    
    private int umpireNumber;
 
 @Override
 public void run() {
  System.out.println("Umpire " + umpireNumber + " Moving to Position");
        try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("Umpire " + umpireNumber + " Set at Position");
  
        try {
   cyclicBarrier.await();
  } catch (InterruptedException | BrokenBarrierException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println("Umpire - " + umpireNumber + " all set");
 
  
 }

 public int getUmpireNumber() {
  return umpireNumber;
 }

 public void setUmpireNumber(int umpireNumber) {
  this.umpireNumber = umpireNumber;
 }

 public CyclicBarrier getCyclicBarrier() {
  return cyclicBarrier;
 }

 public void setCyclicBarrier(CyclicBarrier cyclicBarrier) {
  this.cyclicBarrier = cyclicBarrier;
 }
 
}


CyclicBarrierPlayers.java - This is a Java thread to initialize all the players. All 11 players calls the await() method to notify that we are all set and waiting for rest of the players to move to the position. As soon as 11th player calls await() method, main class moves forward and allows a match to start.
package com.cyclicbarrier.learning;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierPlayers implements Runnable {

    private CyclicBarrier cyclicBarrier;
    
    private int playerNumber;
 
 @Override
 public void run() {
  System.out.println("Player " + playerNumber + " Moving to Fielding Position");
        try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  System.out.println("Player " + playerNumber + " Fielding Position Set");
  
        try {
   cyclicBarrier.await();
  } catch (InterruptedException | BrokenBarrierException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
        System.out.println("Player - " + playerNumber + " all set");
 }

 public CyclicBarrier getCyclicBarrier() {
  return cyclicBarrier;
 }

 public void setCyclicBarrier(CyclicBarrier cyclicBarrier) {
  this.cyclicBarrier = cyclicBarrier;
 }

 public int getPlayerNumber() {
  return playerNumber;
 }

 public void setPlayerNumber(int playerNumber) {
  this.playerNumber = playerNumber;
 }
 
}


Output -
Match about to Start
Initializing Umpires
Umpires Thread Started
Initializing Players
Umpire 1 Moving to Position
Umpire 2 Moving to Position
Player 1 Moving to Fielding Position
Player 2 Moving to Fielding Position
Player 3 Moving to Fielding Position
Player 4 Moving to Fielding Position
Player 5 Moving to Fielding Position
Player 6 Moving to Fielding Position
Player 7 Moving to Fielding Position
Player 8 Moving to Fielding Position
Player 9 Moving to Fielding Position
Players Thread Started
Player 10 Moving to Fielding Position
Player 11 Moving to Fielding Position
Umpire 1 Set at Position
Umpire 2 Set at Position
Player 1 Fielding Position Set
Player 4 Fielding Position Set
Player 5 Fielding Position Set
Player 8 Fielding Position Set
Player 3 Fielding Position Set
Player 2 Fielding Position Set
Player 9 Fielding Position Set
Player 7 Fielding Position Set
Player 6 Fielding Position Set
Player 11 Fielding Position Set
Player 10 Fielding Position Set
Player - 10 all set
Umpire - 1 all set
Players and Umpires all set at their respective Positions. Lets start a Game
Umpire - 2 all set
Player - 1 all set
Player - 5 all set
Player - 4 all set
Player - 8 all set
Player - 7 all set
Player - 9 all set
Player - 6 all set
Player - 11 all set
Player - 2 all set
Player - 3 all set


Its clearly visible, main client prints "Players and Umpires all set at their respective Positions. Lets start a Game" only when all the Umpire and Player threads have called the await() method. Till then it was in wait state.

Sunday, December 9, 2018

Class Level Locking In Java

5:59 AM 0
Class Level Locking In Java

Class level locking is synchronizing a block of code at a class level or static method itself so that even if multiple threads exists on same or different objects of class but only one thread can enter into the synchronized block or static synchronized method.

It means if 10 instances of a class exists in JVM then only one thread can acquire class level lock. In case of static methods, the lock is always applied on class.

Class level locking is achieved using below 2 options -
public void syncMethod() {
        synchronized (ClassLevelLockingImpl.class) {
  }
 }
}


public static synchronized void syncMethod() {}


As soon as thread entered Synchronized block, thread acquired class object. Thread will leave lock when it exits synchronized block and only after this another waiting thread may enter the block.

Here is the implementation of Class level lock

ClassLevelLockingClient.java - In this implementation, 2 objects are created of Thread class that has class level lock implementation and both threads are started at the same time. Since the lock is applied on a lock, only 1 thread enters into the synchronized block and other enters in wait state
package com.learning.objectclasslocking;

public class ClassLevelLockingClient {

    public static void main(String args[]) {
        int count = 0;
        ClassLevelLockingImpl objectLevelLockingOne = new ClassLevelLockingImpl();
        objectLevelLockingOne.setTime(4000);
        objectLevelLockingOne.setCount(++count);
        new Thread(objectLevelLockingOne).start();

        ClassLevelLockingImpl objectLevelLockingTwo = new ClassLevelLockingImpl();
        objectLevelLockingTwo.setTime(1000);
        objectLevelLockingTwo.setCount(++count);
        new Thread(objectLevelLockingTwo).start();

        System.out.println("Client ends");
    }
}


ClassLevelLockingImpl.java - This is a thread class that has implemented Class level lock
package com.learning.objectclasslocking;

public class ClassLevelLockingImpl implements Runnable {

    public void syncMethod() {
        synchronized (ClassLevelLockingImpl.class) {
            System.out.println("Sync Method Starts " + count);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sync Method Ends " + count);
        }
    }

    public void run() {
        this.syncMethod();
    }

    private int count;

    private int time;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
}


Output -
Client ends
Sync Method Starts 1
Sync Method Ends 1
Sync Method Starts 2
Sync Method Ends 2

Object Level Locking In Java

5:07 AM 0
Object Level Locking In Java

Object level locking is synchronizing a block of code or whole method itself so that -
1) Different Threads on Different Instance of Object - Threads on different objects may enter the synchronized block of code at the same time. This means multiple objects of same class that exists in memory has their own individual lock.

2) Different Threads Same Instance of Object - Multiple threads on same object may exists in memory but only one thread on that object instance can enter synchronized block at a time. All other threads will be in wait state.

There are two flavors of Object lock
public void syncMethod() {
        synchronized (this) {
  }
 }


public synchronized void syncMethod() { }


Here is the implementation of Case 1 - Different Threads on Different Instance of Object

ObjectLevelLockingImpl.java - Thread Class
package com.learning.objectclasslocking;

public class ObjectLevelLockingImpl implements Runnable {

    public void syncMethod() {
        synchronized (this) {
            System.out.println("Sync Method Starts " + count);
            try {
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Sync Method Ends " + count);
        }
    }

    public void run() {
        this.syncMethod();
    }

    private int count;

    private int time;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
}


ThreadsOnDifferentObjectLocking.java - This implementation is for Different Threads on Different Instance of Object - Threads on different objects may enter the synchronized block of code at the same time. This means multiple objects of same class that exists in memory has their own individual lock. In this class, 2 objects of class ObjectLevelLockingImpl are created and 2 threads are started at the same time. Observe the output, both the threads are able to enter the synchronized method at the same time.
package com.learning.objectclasslocking;

public class ThreadsOnDifferentObjectLocking {

    public static void main(String args[]) {
        int count = 0;
        ObjectLevelLockingImpl objectLevelLockingOne = new ObjectLevelLockingImpl();
        objectLevelLockingOne.setTime(4000);
        objectLevelLockingOne.setCount(++count);
        new Thread(objectLevelLockingOne).start();

        System.out.println("First Thread Started");

        ObjectLevelLockingImpl objectLevelLockingTwo = new ObjectLevelLockingImpl();
        objectLevelLockingTwo.setTime(1000);
        objectLevelLockingTwo.setCount(++count);
        new Thread(objectLevelLockingTwo).start();

        System.out.println("Second Thread Started");
        System.out.println("Client ends");
    }
}


Output -
First Thread Started
Second Thread Started
Client ends
Sync Method Starts 1
Sync Method Starts 2
Sync Method Ends 2
Sync Method Ends 1


ThreadsOnSameObjectLocking.java - Different Threads Same Instance of Object - Multiple threads on same object may exists in memory but only one thread on that object instance can enter synchronized block at a time. All other threads will be in wait state.
package com.learning.objectclasslocking;

public class ThreadsOnSameObjectLocking {

    public static void main(String args[]) {
        int count = 0;
        ObjectLevelLockingImpl objectLevelLockingOne = new ObjectLevelLockingImpl();
        objectLevelLockingOne.setTime(4000);
        objectLevelLockingOne.setCount(++count);

        Thread threadOne = new Thread(objectLevelLockingOne);
        threadOne.setName("Thread One");

        Thread threadTwo = new Thread(objectLevelLockingOne);
        threadTwo.setName("Thread Two");

        threadOne.start();
        threadTwo.start();
        System.out.println("Main Ends");
    }
}


Output -
Main Ends
Sync Method Starts 1
Sync Method Ends 1
Sync Method Starts 1
Sync Method Ends 1

Java Lock - java.util.concurrent.locks.Lock Real Time Example

2:01 AM 0
Java Lock Real Time Example

Lock in Java has been introduced in JDK 1.5 to enable synchronize mechanism. They are similar to synchronized blocks with additional features. Lock is an interface in Java and there are different implementations of Lock

1) ReentrantLock - It applies lock to a block of code in a method or block of code in different methods too. Unlike synchronized block that is applied to a whole method or a block of code within a method, Locks can be applied to blocks of code within 1 method or more than 1 method. Lock applied in one method can be unlocked in another method too.
2) ReentrantReadWriteLock - This implementation is used to perform locking when there are multiple readers and writers on a single source.

Lock interface has below important methods
1) lock() - This method acquires a lock on a resource. If a lock is not available then a thread waits indefinitely until the block is released.
2) unlock() - This method unlock the locked instance and allow another threads in waiting state to acquire a lock.

Good practice is to call unlock() method always in a finally block, otherwise in case of an exception after lock() method execution, it will remain in an infinite lock and cause deadlock situation.

Here is a sample implementation of the Lock Interface
LockThread.java - This is a thread which locks and unlocks the Lock instance created by client class. This implementation waits for infinite since it is using the lock() method. In the next implementation we will see lock implementation with time out.
package com.learning.locks;

import java.util.concurrent.locks.Lock;

public class LockThread implements Runnable {

    private Lock lock;

    private int count;

    private int time;

    public void run() {
        lock.lock();
        System.out.println("Thread " + this.count + " got locked");
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        lock.unlock();
        System.out.println("Thread " + this.count + " got unlocked");
    }

    public Lock getLock() {
        return lock;
    }

    public void setLock(Lock lock) {
        this.lock = lock;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
}


LockClient.java - 3 Threads are created that takes different times to complete processing. The thread that acquires a lock is on random basis.
package com.learning.locks;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockClient {

    public static void main(String args[]) {
        Lock lock = new ReentrantLock();
        int lockCount = 0;

        LockThread lockThreadOne = new LockThread();
        lockThreadOne.setLock(lock);
        lockThreadOne.setCount(++lockCount);
        lockThreadOne.setTime(10000);

        LockThread lockThreadTwo = new LockThread();
        lockThreadTwo.setLock(lock);
        lockThreadTwo.setCount(++lockCount);
        lockThreadTwo.setTime(4000);

        LockThread lockThreadThree = new LockThread();
        lockThreadThree.setLock(lock);
        lockThreadThree.setCount(++lockCount);
        lockThreadThree.setTime(1000);

        new Thread(lockThreadTwo).start();
        new Thread(lockThreadOne).start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(lockThreadThree).start();
        System.out.println("All the locks initialized");

    }
}


Output -
Thread 2 got locked
All the locks initialized
Thread 1 got locked
Thread 2 got unlocked
Thread 1 got unlocked
Thread 3 got locked
Thread 3 got unlocked

Saturday, December 8, 2018

Java concurrency – CountDownLatch Real Time Example

8:27 AM 0
Java concurrency – CountDownLatch Example

CountDownLatch is the class introduced in Concurrency API in JDK 1.5. CountDownLatch allows the application to wait for the rest of the threads to get over. In a scenario, it is required a single primary thread to wait until all the thread finishes its processing. To achieve this, CountDownLatch is used.

CountDownLatch is initialized with an integer value. This integet value suggests, for how many count down it needs to wait. Every time a thread calls "countDown()" method, the initialized count reduces by 1. The moment count reaches 0, main thread resumes further.

Different Scenarios -
1) If CountDownLatch is initialized with 0, and "countDown()" is called 3 times in different or same threads - Client does not wait since the count itself is 0 during initialization.
2) If CountDownLatch is initialized with 1, and "countDown()" is called 3 times in different or same threads - Client will move forward as soon as 1st "countDown()" is called.
3) If CountDownLatch is initialized with 3, and "countDown()" is called 3 times in different or same threads - Client will move forward only after 3rd "countDown()" is called.

Real Time Scenario -
Consider a Bank that works from morning 9 AM to 3 PM. Bank will be closed only when it serves all the clients that has entered before 3 PM. Bank will remain open unless all customers leave the premises.

In this case, Bank is a CountDownLatch Main Client on which "await()" method is applied and Customers are the ones who performs "countDown()" on the latch.

Here is a realtime example of CountDownLatch
CountDownLatchClient.java - It creates the CountDownLatch object with count 2 and enters in await() state for threads to call "countDown()" atleast twice. 2 threads will be created and CountDownLatchClient will wait for them to finish processing.
package com.learning.countdownlotch;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchClient {

    public static void main(String args[]) {

        final CountDownLatch latch = new CountDownLatch(2);

        CountDownThread countDownThreadOne = new CountDownThread();
        countDownThreadOne.setLatch(latch);
        countDownThreadOne.setCount(1);
        countDownThreadOne.setTime(1000);

        new Thread(countDownThreadOne).start();

        CountDownThread countDownThreadTwo = new CountDownThread();
        countDownThreadTwo.setLatch(latch);
        countDownThreadTwo.setCount(2);
        countDownThreadTwo.setTime(3000);

        new Thread(countDownThreadTwo).start();

        try {
            latch.await();
            System.out.println("Main Ends");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


CountDownThread.java - This is a thread class which calls the "countDown()" on the CountDownLatch Object
package com.learning.countdownlotch;

import java.util.concurrent.CountDownLatch;

public class CountDownThread implements Runnable {
    private CountDownLatch latch;

    private int count;

    private int time;

    public void run() {

        try {
            System.out.println("CountDownThread Starts " + getCount());
            Thread.sleep(time);
            System.out.println("CountDownThread Ends " + getCount());
            latch.countDown(); //reduce count of CountDownLatch by 1
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public CountDownLatch getLatch() {
        return latch;
    }

    public void setLatch(CountDownLatch latch) {
        this.latch = latch;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getTime() {
        return time;
    }

    public void setTime(int time) {
        this.time = time;
    }
}


Output -
CountDownThread Starts 1
CountDownThread Starts 2
CountDownThread Ends 1
CountDownThread Ends 2
Main Ends

Saturday, September 15, 2018

Node JS Sort npm custom ArrayList using compare method

10:16 PM 0
Node JS Sort npm custom ArrayList using compare method

Arraylist is the collection in Node JS that stores the collection of objects. In below example we have a custom collection of ArrayList objects with two properties:
1) Name
2) Age

We will implement both the sort operations, one based on age and second based on name in ascending order. A simple collection of integer or string can be sorted using the sort() method. But in case of custom objects, we need to implement the compare function that defines the sorted algorithm.

We have implemented 2 different sort methods:
1) sortListByAge
2) sortListByName

First method implements the sort compare based on Age property and second implements based on Name. Here is the complete implementation.

/*jshint esversion: 6 */ 
var DELAY = 1000;
var ArrayList = require('arraylist');

var list = new ArrayList();
list.add([{ name: 'Edward', age: 21 },
   { name: 'Sharpe', age: 37 },
   { name: 'And', age: 45 },
   { name: 'The', age: -12 },
   { name: 'Magnetic', age: 13 },
   { name: 'Zeros', age: 37 }]);

module.exports = {
 sortListByAge() {
     return new Promise((resolve) => {
       setTimeout(() => {
        list.sort(function (a, b) {
         return a.age - b.age;
       });
      console.log("Sorted List By Age : " + list); 
         resolve(list);
       }, DELAY);
     });
   },
   sortListByName() {
      return new Promise((resolve) => {
        setTimeout(() => {
         list.sort(function(a, b) {
          var nameA = a.name.toUpperCase();
          var nameB = b.name.toUpperCase();
          if (nameA < nameB) {
            return -1;
          }
          if (nameA > nameB) {
            return 1;
          }
          return 0;
        });
        console.log("Sorted List By Name : " + list); 
          resolve(list);
        }, DELAY);
      });
    },
};


When we run above service, below output is generated
1) sortListByAge - [{"name":"The","age":-12},{"name":"Magnetic","age":13},{"name":"Edward","age":21},{"name":"Sharpe","age":37},{"name":"Zeros","age":37},{"name":"And","age":45}]
2) sortListByName - [{"name":"And","age":45},{"name":"Edward","age":21},{"name":"Magnetic","age":13},{"name":"Sharpe","age":37},{"name":"The","age":-12},{"name":"Zeros","age":37}]