I have a store which has a number of queues. Each queue has a number of max clients that can wait to be served and I can write the number of queues. My store would have to close after a certain amount of minutes that I give. The problem is that it doesn't. It just generates clients that are served and generates etc etc etc.

import java.util.List;
import java.util.Timer;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        //long startTime = System.currentTimeMillis();
                long endTime;
                int nrCozi;
                int nrClientiMax;

                System.out.println("Introduceti cate minute va fi deschis magazinul: ");
                Scanner in = new Scanner(System.in);
                endTime = in.nextInt();
        endTime = System.currentTimeMillis() + endTime * 1000 * 60;

                System.out.println("Introduceti numarul de cozi: ");
                nrCozi = in.nextInt();

                System.out.println("Introduceti numarul maxim de clienti per coada: ");
                nrClientiMax = in.nextInt();
                System.out.println("clienti" + nrClientiMax);

        List<Coada> cozi = CoadaUtil.create(nrCozi, endTime);
        CoadaUtil.startCozi(cozi);

        Timer timer = new Timer();
        timer.schedule(new ClientGenerator(nrClientiMax, cozi), 0, (int) (Math.random()* 10 * 1000));


    }

}

This is the Queue class

import java.util.ArrayList;
import java.util.List;

public class Coada implements Runnable {

    private List<Client> clients;
    private long closingTime;
        private long sleepTime = 0;
    private String nume;

    public Coada(long closingTime) {
        clients = new ArrayList<Client>();
        this.closingTime = closingTime;
    }

    public void setNume(String nume) {
        this.nume = nume;
    }

    public void addClient(Client c) {
        clients.add(c);
    }

    private Client pop() {
        if (clients.size() > 0) {
            Client c = clients.get(0);
            clients.remove(0);
            return c;
        }
        return null;
    }

    @Override
    public void run() {
        Client c = this.pop();
        long currentTime = System.currentTimeMillis();
        while (c != null || currentTime < closingTime) {
            if (c != null) {    
                            try {
                    System.out.println("Sunt coada " + this.nume + " si " +
                            "tratez clientul " + c.getNume());
                    Thread.sleep(c.getWaitingTime() * 1000);
                } catch (InterruptedException e) {
                }
            }
            currentTime = System.currentTimeMillis();
            c = this.pop();
         if(c==null){
                     this.sleepTime+=System.currentTimeMillis() - currentTime;
                     this.sleepTime++;
                }
                }
               // System.out.println("Coada " + this.nume +" a dormit " + this.sleepTime );

    }

    public int getClientSize() {
        return clients.size();
    }

    public String getNume() {
        return this.nume;
    }

        public long getSleepTime(){
            return this.sleepTime;
        }


}

ClientGenerator class

import java.util.List;
import java.util.TimerTask;


public class ClientGenerator extends TimerTask {

    private int nrClients;

    private List<Coada> cozi;

    public ClientGenerator(int i, List<Coada> cozi) {
        this.nrClients = i;
        this.cozi = cozi;
    }

    @Override
    public void run() {
        for (int i = 0; i < nrClients; i++) {
                        System.out.println("!!!!!!!!!!!!!Client" + i +" din " + nrClients);
            Client client = new Client((int) (Math.random() * 10), i + ""); // timp random
                        System.out.println("Clientul " + client.getNume() + " asteapta " + client.getWaitingTime()*10 + " secunde");

                        Coada coada = CoadaUtil.gasesteCoadaOptima(cozi);
            coada.addClient(client);
            System.out.println("Am adaugat clientul " + i + " la" +
                    " coada " + coada.getNume());
        }

    }

}

CoadaUtil class

import java.util.ArrayList;
import java.util.List;


public class CoadaUtil {

    private CoadaUtil(){}

    public static List<Coada> create(int nrCozi, long endTime) {
        List<Coada> cozi = new ArrayList<Coada>();
        for (int i = 0; i < nrCozi; i++) {
            Coada c = new Coada(endTime);
            c.setNume(i + "");
            cozi.add(c);
        }
        return cozi;
    }

    public static void startCozi(List<Coada> cozi) {
        for (int i = 0; i < cozi.size(); i++) {
            Thread t = new Thread(cozi.get(i));
            t.start();
        }
    }

    public static Coada gasesteCoadaOptima(List<Coada> cozi) {
        Coada c = cozi.get(0);
        for (Coada coada : cozi) {
            if (coada.getClientSize() < c.getClientSize()) {
                c = coada;
            }
        }
        return c;
    }

}

My guess is that it has to do with the System.currentTimeMillis(); from Main class.

Thanks, Dragos

share|improve this question
Can you show the code for CoadaUtil class? – dcernahoschi Mar 27 at 20:35
This belongs on codereview.stackexchange.com – Gray Mar 27 at 20:35
I added CoadaUtil – Dragos Mihai Marcean Mar 27 at 20:53

1 Answer

The program is not stopping because your Timer is generating clients forever, long after your threads that process them have finished.

One easy way to exit the program after your processing threads(Coada objects) have finished is to make the Timer a daemon thread:

Timer timer = new Timer(true);

The JVM will exit when only daemon threads are running.

From the java doc of Timer:

After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating.

share|improve this answer
Thanks:D That worked with the infinite loop. Now I have to figure out how to combine the endTime values so I can control how many minutes/seconds it runs. – Dragos Mihai Marcean Mar 27 at 22:04
Apparently for the save values it has different ending time. Sometime very short, sometimes again looks like infinite loop – Dragos Mihai Marcean Mar 27 at 22:15
The code is full of issues regarding concurrency and multithreading. But one of the problems that prevents the program to exit is the above one in my answer. Try removing all the code from the run method in class Coada and you will see that the program will not exit until you make the Timer a daemon thread. – dcernahoschi Mar 27 at 22:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.