Java:使用线程的应用程序中的无限循环

时间:2013-03-27 20:22:30

标签: java multithreading timer infinite-loop

我有一个有许多队列的商店。每个队列都有许多可以等待服务的最大客户端,我可以写入队列数。我的商店必须在我给出的一定时间后关闭。问题是它没有。它只生成服务和生成等的客户端等。

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));


    }

}

这是队列类

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类

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类

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;
    }

}

我的猜测是它与System.currentTimeMillis()有关;来自Main class。

谢谢, 德拉戈什

1 个答案:

答案 0 :(得分:1)

该程序没有停止,因为您的Timer在处理它们的线程完成后很久就会永远生成客户端。

在处理线程(Coada对象)完成后退出程序的一种简单方法是使Timer成为守护程序线程:

Timer timer = new Timer(true);

只有守护程序线程正在运行时,JVM才会退出。

来自Timer的java文档:

  

对Timer对象的最后一次实时引用消失后全部消失   未完成的任务已完成执行,计时器的任务执行   线程优雅地终止(并成为垃圾   采集)。 但是,这可能需要很长时间才能发生。通过   默认情况下,任务执行线程不作为守护程序线程运行,所以   它能够阻止应用程序终止。