Multi-threading example in Java

Default featured post

In the previous post I discussed about multi-threading concepts and provided a case study to understand the principles better. In this post the solution of the case study is given with detailed explanation about it.

As mentioned, the first thing that program should do is to categorize mails, this is rather simple and no need to involve multi-threading and it can be resolved with a simple if, else condition.

Check the below sample code for better understanding,

public class Mail {
public void doSendMails() {
// The main unorganized mail queue
Vector mailQueue = new Vector();
mailQueue = getAllMails();
Vector northMails = new Vector();
Vector southMails = new Vector();
Vector eastMails = new Vector();
Vector westMails = new Vector();
// Start categorizing the mails
for (int cnt = 0; cnt < mailQueue.size; cnt++) {
Mails oneMail = mailQueue.get(cnt);
if (oneMail.getMailAdress().toUpperCase.contains("NORTH")) {
northMails.add(oneMail);
} else if (oneMail.getMailAdress().toUpperCase.contains("SOUTH")) {
southMails.add(oneMail);
} else if (oneMail.getMailAdress().toUpperCase.contains("EAST")) {
eastMails.add(oneMail);
} else {
westMails.add(oneMail);
}
}
Vector<vector> allMails = new Vector();
allMails.add(northMails);
allMails.add(southMails);
allMails.add(eastMails);
allMails.add(southMails);
}
}
view raw Mail.java hosted with ❤ by GitHub

We have categorized the main queue to 4 groups (vectors). Now it is time to send each mail man (vector) to operate separately (run in a separate thread) the same task which is mails distribution. However, we should bear in mind about the last portion of the case study which refers to security man waiting, therefore, we need to keep track of the threads and to this so need to create an array to holds thread reference. Check the below code,

public class Mail {
public void doSendMails() {
//Creating ArrayList of the ThreadClass to hold reference of the threads
ArrayList<ThreadClass> mailManThreads = new ArrayList();
for (int cnt = 0; cnt < mailManThreads.size(); cnt++) {
Vector oneMailQueue = new Vector();
oneMailQueue = allMails.get(cnt);
ThreadClass oneMailManThread = new ThreadClass();
oneMailManThread.start(oneMailQueue);
mailManThreads.add(oneDealerThread);
}
// Joins all threads to main thread to avoid main thread to continue without finishing the rest of threads
for (int cnt = 0; cnt < mailManThreads.size(); cnt++) {
mailManThreads.get(cnt).join();
}
}
}
view raw Mail.java hosted with ❤ by GitHub

The only remaining and most challenging part is to avoid mailmen (threads) to access to the notebook (resource) at the same time. If one resource will be access at the same time, race condition might occur and the value of one resource might be changed without notifying others resource holders. To avoid such a problem the best approach is using locking mechanism in which resource cannot be allocated to more than one thread at the same time. This is done with using synchronized keyword. The entire operation of mail main is written in a separate class file which is as well.

public class ThreadClass extends Thread {
private Thread thread;
private Vector<Mails> mailQueue = new Vector<Mails>();
public void start(Vector<Mails> mailQueue) {
if (thread == null) {
this.mailQueue = mailQueue;
thread = new Thread(this);
thread.start();
}
}
public void run() {
//Update share resource
synchronized (this) {
updateNoteBook();
}
// Other operation here
}
public static synchronized updateNoteBook() {
// Do whatever necessary
// The function can be called by one thread at the same time
}
}

As you can see multi-threading is not as cumbersome as it seems, just you need to learn the basic concept first and find an example (preferably real world) to implement to become master of it 😉