Showing posts with label Java Core. Show all posts
Showing posts with label Java Core. Show all posts

Wednesday, 17 June 2015

Part 4: Java thread synchronization and wait/notify mechanism

Wait notify mechanism with synchronization
In posts of thread in Java, I wrote four posts about this topic:
Part 1. Basic Thread in java. How to create them?
Part 2. Thread in java: method revisiting
Part 3. Thread in Java: Thread synchronization (or thread safe)
Part 4: Java thread synchronization and wait/notify mechanism

As mentioned in previous post [Part 3: Java Thread], we never know when the shared resource is set or not yet set. We cannot make forever loop to check the state of that resource. One solution for this solution is to use wait/notify mechanism in java. The way to do that is we use [object.wait()] to wait for other threads set the data. In the threads setting the data, we call [object.notify()] to notify all threads are waiting for resource wake up, and doing necessary process. Look at example below to see how wait/notify works.

import java.util.LinkedList;

public class SynchronizeDemo {
       public static void main(String[] args) {
              LinkedList resources = new LinkedList();
              PusherThread pt = new PusherThread(resources, 100);
              pt.start();

              PrinterThread print1 = new PrinterThread(resources, "Print1", 100);
              PrinterThread print2 = new PrinterThread(resources, "Print2", 50);
              print1.start();
              print2.start();
              System.out.println("All threads are started!!!!");
       }

}

class PusherThread extends Thread {
       private LinkedList rs;

       public PusherThread(LinkedList rs, int no) {
              this.noOfElement = no;
              this.rs = rs;
       }

       private int noOfElement = 10;

       public void run() {
              for (int i = 0; i < noOfElement; i++) {
                     synchronized (rs) {
                           rs.add(i);
                       rs.notify();
                           try {
                                  Thread.sleep(300);
                           } catch (InterruptedException e) {
                           }
                     }
              }
              System.out.println(noOfElement + " numbers are added to the list!");
       }
}

class PrinterThread extends Thread {
       private LinkedList rs;

       public PrinterThread(LinkedList rs, String name, long sleepTime) {
              this.rs = rs;
              this.sleepTime = sleepTime;
              this.threadName = name;
       }

       private boolean start = true;
       private long sleepTime = 100;

       public void stop(boolean val) {
              this.start = val;
       }

       public void sleepIn(long val) {
              this.sleepTime = val;
       }

       private String threadName;

       public void nameMe(String val) {
              this.threadName = val;
       }

       public void run() {
              while (start) {
                     // synchronize helps us only one value is removed
                     synchronized (rs) {
                           if (!rs.isEmpty()) {
                                  int val = rs.remove();// remove a value
                                  System.out.println("[" + threadName + "], Removed :" + val);
                           }else{
                           System.out.println("No more data, waiting....");
                           try {
                                rs.wait();
                           } catch (InterruptedException e) {
                           }
                           }
                     }
                     try {
                           Thread.sleep(sleepTime);
                     } catch (InterruptedException e) {
                     }
              }
       }

}

Tuesday, 16 June 2015

Part 3. Thread in Java: Thread synchronization (or thread safe)

Part 3. Thread synchronization (or thread safe)
In summary, synchronization helps sharing data (by multiple threads) consistency.
We know that, in multiple threading application, all the threads may share one or more resource across application. For example, they may share a queue/list contains data about employee to process, one or more threads are used to read data from another resource, and put it into this queue, and one or more threads are used to process data in this queue. In the multi-threaded application, it is very important to consist sharing data. One data cannot be processed more than one time. In this case, we use synchronization in java to solve problem.
Note: sometime they call this as thread-safe.
There are two ways to synchronize resource: synchronize block and synchronize methods.
  1. Synchronize block:
synchronized (resource) {
}
Where: resource is an object that are used to share between threads.
  1. Synchronize methods:
public synchronized void put(Object data){
//other stuff
}
public synchronized Object get(){
//other stuff
return null;
}
These two methods are one of resource “container” where you want to share between threads.
Example, we have one thread for pushing data, and two threads for getting data. The first getting data thread will wait 0.5 second for each time take the data, the second getting data thread waits only 0.3 second.
Note that, in this example, I used LinkedList as a sharing resource between threads, hence I have to use synchronized block. However, there are many List (Vector), Queue (like ConcurrentLinkedList) can be used instead, it already provided synchronized methods.
import java.util.LinkedList;

public class SynchronizeDemo {
public static void main(String[] args) {
LinkedList resources = new LinkedList();
PusherThread pt = new PusherThread(resources, 300);
pt.start();

PrinterThread print1 = new PrinterThread(resources, "Print1", 300);
PrinterThread print2 = new PrinterThread(resources, "Print2", 200);
print1.start();
print2.start();
System.out.println("All threads are started!!!!");
}

}

class PusherThread extends Thread {
private LinkedList rs;

public PusherThread(LinkedList rs, int no) {
this.noOfElement = no;
this.rs = rs;
}

private int noOfElement = 10;

public void run() {
for (int i = 0; i < noOfElement; i++) {
synchronized (rs) {
rs.add(i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
}
System.out.println(noOfElement + " numbers are added to the list!");
}
}

class PrinterThread extends Thread {
private LinkedList rs;

public PrinterThread(LinkedList rs, String name, long sleepTime) {
this.rs = rs;
this.sleepTime = sleepTime;
this.threadName = name;
}

private boolean start = true;
private long sleepTime = 100;

public void stop(boolean val) {
this.start = val;
}

public void sleepIn(long val) {
this.sleepTime = val;
}

private String threadName;

public void nameMe(String val) {
this.threadName = val;
}

public void run() {
while (start) {
// synchronize helps us only one value is removed
synchronized (rs) {
if (!rs.isEmpty()) {
int val = rs.remove();// remove a value
System.out.println("[" + threadName + "], Removed :" + val);
}
}
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
}
}
}
Output:
As result from program, we don’t know when the linked list object is empty. If we don’t set the “start” Boolean to false, these PrinterThread will run forever. To solve this problem, we use Wait/notify mechanism. Reading next post: Part 4. Wait/notify mechanism.