Java - Simple multithreaded programming

By xngo on February 27, 2019

The code below shows that the Manager class will give a job to each worker. As soon as a worker completes its job, a new job is assigned to the free worker.

Manager class

import java.util.ArrayList;
 
public class Manager
{
  public static void main(String[] args)
  {
    // Variables
    int iNumOfWorkers = 3;// Number of workers.
    int iNumOfJobs = 11;  // Number of jobs.
    long lWaitTime = 1000;// Time lapse before asking who workers are free.
 
    // Create jobs list.
    ArrayList<String> aJobsList = new ArrayList<String>();
    for(int j=0; j<iNumOfJobs; j++)
      aJobsList.add((j+1)+"");
 
    // Create workers
    Worker aWorkers[] = new Worker[iNumOfWorkers];
    for(int i=0; i<iNumOfWorkers; i++)
    {
      aWorkers[i] = new Worker();
    }
 
 
    System.out.println("Start giving jobs to workers("+aJobsList.size()+" jobs)");    
 
    // Work until there is no job left.
    while(aJobsList.size()>0)
    {
      // Get a list of which workers are free.
      ArrayList<Integer> aFreeWorkersIndex = getFreeWorkers(aWorkers);
 
      // Show free workers.
      displayFreeWorkers(aFreeWorkersIndex);
 
      // Give each worker a job.
      for(int j=0; j<aFreeWorkersIndex.size(); j++)
      {
        int iWorkerId = aFreeWorkersIndex.get(j).intValue();
        aWorkers[iWorkerId] = new Worker();
 
        // Custom method used to pass data to the worker.
        aWorkers[iWorkerId].set("Worker"+iWorkerId, aJobsList);
 
        aWorkers[iWorkerId].start();
      }
 
      // Wait X time before asking who are free to take a job.
      try
      {
        Thread.sleep(lWaitTime);
      }
      catch(Exception ex)
      {
        System.out.println(ex);
      }
    }
 
    System.out.println("End giving jobs to workers.");
 
  }
 
  /**
   * Get the id of workers that are free.
   * @param aWorkers
   * @return IDs of workers that are free.
   */
  public static ArrayList<Integer> getFreeWorkers(Worker aWorkers[])
  {
    ArrayList<Integer> aFreeWorkersIndex = new ArrayList<Integer>();
 
    // Go through each worker and see who are free to take new job.
    for(int i=0; i<aWorkers.length; i++)
    {
      if(!aWorkers[i].isAlive())
      {
        aFreeWorkersIndex.add(new Integer(i));
      }
    }
    return aFreeWorkersIndex;
  }
 
  public static void displayFreeWorkers(ArrayList<Integer> aWorkers)
  {
    // No free workers. Get out.
    if(aWorkers.size()==0)
    {
      System.out.println("No free workers.");
      return;
    }
 
    // Display free workers.
    System.out.print("Free workers IDs: ");
    for(int i=0; i<aWorkers.size()-1; i++)
      System.out.print(aWorkers.get(i)+", ");
    System.out.print(aWorkers.get(aWorkers.size()-1)); // Display last worker's ID.
    System.out.println();
  }
}

Worker class

/**
 * Worker.java
 * Implement what worker should do in this class.
 */
import java.lang.Thread;
import java.util.Random;
import java.util.ArrayList;
 
public class Worker extends Thread 
{
  private String m_sWorkerName = "";
  private ArrayList<String> m_aJobsList = null;
  private String m_sJobName = "";
 
  public Worker()
  {}
 
  /**
   * Demonstrate how to pass values from Manager class to Worker class.
   * @param sWorkerName
   * @param aJobsList
   */
  public void set(String sWorkerName, ArrayList<String> aJobsList)
  {
    this.m_sWorkerName = sWorkerName;
    this.m_aJobsList = aJobsList;
 
    this.getJob();
  }
  /**
   * Get the job and remove it from the job list so that other workers will
   *  not take the same job.
   * Synchronized keyword is used so that other workers can't take the same job.
   */
  private synchronized void getJob()
  {
    if(this.m_aJobsList.size()!=0)
      this.m_sJobName = this.m_aJobsList.remove(0);
  }
 
  /**
   * This method will run when Worker.start() is called.
   * All the logics should be put in here. This is like the main() of a program.
   */
  public void run()
  {
    /**
     * Put a random sleep time to simulate work time.
     */
    Random oRandom = new Random();
    int iSleepTime = oRandom.nextInt(5000);
    System.out.println("\t"+this.m_sWorkerName+": Working on Job"+this.m_sJobName+" for " +iSleepTime +"ms.");
    try
    {
      Thread.sleep(iSleepTime);
    }
    catch(Exception ex)
    {
      System.out.println(ex);
    }
    System.out.println("\t"+this.m_sWorkerName+": Done Job"+this.m_sJobName+".");
  }
 
}

About the author

Xuan Ngo is the founder of OpenWritings.net. He currently lives in Montreal, Canada. He loves to write about programming and open source subjects.