Part 3. Thread synchronization (or thread safe)
In posts of thread in Java, I wrote four posts about this topic:
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.
- Synchronize block:
synchronized (resource) {
}
Where: resource is an object that are used to share between threads.
- 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
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
public PusherThread(LinkedList
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
public PrinterThread(LinkedList
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:
|
No comments:
Post a Comment