0

I have to simulate the activity of a postal office, where an office worker can offer many services like paying bills, send letters etc. I have created a separate application which simulates the incoming clients and store them in the database. The second application has to manage the "clients" from the database and assign to each office worker "clients" that have requested specific tasks. If the office worker is busy then the client should be added in a waiting queue. Each office worker should do the job in a new thread. The problem is that when i run the application only one thread is doing his job. Then the application stops. Anyone has any suggestions on how can i implement this application using multithreading?

Office worker class

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;

import ro.csm.database_access.OperationDatabaseAccess;
import ro.csm.database_access.TaskDatabaseAccess;

public class OfficeWorker {

    //each office worker has a queue of tasks, a list of supported operations, an office and a thread

    private Queue<Task> tasks;
    private List<Operation> supportedOperations;
    private Thread workingThread;
    private Office office;


    //constructor
    public OfficeWorker(Office office){
        this.office = office;
        supportedOperations = OperationDatabaseAccess.getAllSupportedOperations(office.getId());
        workingThread = new Thread();
        workingThread.start();
        setTasks(new LinkedList<Task>());
    }

    //add task to the tasks queue       
    public void addTask(Task task){
        getTasks().add(task);
    }

    //finish the task
    public void work(){

        while(true){
            Task t = getTasks().poll();
            if(t != null){
                TaskDatabaseAccess.setTaskCompleted(t.getId());

                try {
                    Thread.sleep(getCompletionTime(t));
                    workingThread.stop();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }       
    }

    //generate a random completion time for each task considering the minimum time and the maximum time allocated for a task
    private int getCompletionTime(Task t){      

        Operation op = OperationDatabaseAccess.getOperationByTaskId(t.getId());
        int min = op.getMinTime();
        int max = op.getMaxTime();
        Random rand = new Random();             
        return rand.nextInt(max - min + 1) - min;
    }

Main application class

    import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import ro.csm.database_access.OfficeDatabaseAccess;
import ro.csm.database_access.OperationDatabaseAccess;
import ro.csm.database_access.TaskDatabaseAccess;
import ro.csm.models.Office;
import ro.csm.models.OfficeWorker;
import ro.csm.models.Operation;
import ro.csm.models.Task;

public class MainApplication {
    //list of available offices
    static List<Office> offices = OfficeDatabaseAccess.getOffices();
    //list of office workers
    static List<OfficeWorker> workers = createOfficeWorker(offices);



    public static void main(String[] args) {

        while(true){
            //get the list of pending tasks
            List<Task> tasks = TaskDatabaseAccess.getNotStarted();
            for(Task t : tasks){
                //for each task set the status in progress
                TaskDatabaseAccess.setTaskInProgres(t.getId());
                //assign the task to a office worker
                assignTaskToOfficeWorker(t);                
            }
        }       
    }

    public static void assignTaskToOfficeWorker(Task t){
        //create a list of possible workers
        List<OfficeWorker> possibleWorkers = new ArrayList<OfficeWorker>();
        //get the supported operations for each office worker
        for(OfficeWorker ow : getWorkers()){
            List<Operation> supportedOperations = OperationDatabaseAccess.getAllSupportedOperations(ow.getOffice().getId());
            //check if the given task is in the list of supported operations
            for(Operation op : supportedOperations){
                if(op.getId() == t.getIdOperation()){
                    //if the task can be executed by this office worker then add this worker in the list of possible workers
                    possibleWorkers.add(ow);
                }
            }
        }
        //assign the task to the worker that has the smallest queue tasks
        OfficeWorker toBeAssigned = findOWMinTaskInQueue(possibleWorkers);
        toBeAssigned.addTask(t);
        //update the task with the office number
        TaskDatabaseAccess.updateTaskWithOfficeInformation(toBeAssigned.getOffice().getId(), t.getId());
        //complete the task
        toBeAssigned.work();
    }

    public static List<OfficeWorker> createOfficeWorker(List<Office> offices){
        List<OfficeWorker> workers = new ArrayList<OfficeWorker>();
        for(Office office : offices){
            OfficeWorker ow = new OfficeWorker(office);
            workers.add(ow);
        }
        return workers;
    }

    public static OfficeWorker findOWMinTaskInQueue(List<OfficeWorker> workers){
        Collections.sort(workers, new Comparator<OfficeWorker>() {
            public int compare(final OfficeWorker ow1, final OfficeWorker ow2){
                return ((Integer) ow1.getTasks().size()).compareTo((Integer)ow2.getTasks().size());

            }
        }); 
        return  workers.get(0);
    }
2
  • 2
    workingThread = new Thread();workingThread.start(); : you don't pass any Runnable to the thread, so it has nothing to do. Also, LinkedList is not thread-safe, and is not blocking. Commented May 26, 2014 at 14:47
  • 1
    Side note: Never use the stop() method of Thread. It has been deprecated for over 15 years now, for good reason, as it can compromise thread safety (including in objects you aren't managing). Always write your Runnable to gracefully exit when receiving an interrupt, and then have your other code stop the Thread by interrupting it. Commented May 29, 2014 at 0:31

1 Answer 1

1

The problem is that you not doing any multitasking. Your OfficeWorker is just class that creates empty thread and starts it.

Here is basic example:

  new Thread(new Runnable() {
      public void run() {
        //do something
      }
  }).start();

Please read this docs http://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html to understand more.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.