Завершение темы - PullRequest
       11

Завершение темы

0 голосов
/ 09 июня 2018

Я пытаюсь смоделировать банковскую услугу.До сих пор я могу случайным образом генерировать клиентов со случайным временем, и кассиры будут обслуживать их, если они не заняты.Моя проблема возникает, когда симуляция должна закончиться ... это не так.Клиенты перестают генерироваться, но кассир продолжает ждать клиентов.Я пробовал разные подходы, но не получилось.Это код перед попыткой решения.

Это CustomerGenerator:

    @Override
public void run() {
    while (currentTime != openTime) {
        double accept = Math.random();
        if (accept >= 0.6) {
            addCustomerToQueue();
            System.out.println("Customer in line.");
        } else {
            System.out.println("Waiting for a customer.");
        }
        try {
            currentTime += 1000;
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private synchronized void addCustomerToQueue() {
    Customer customer = new Customer(placeInLine + 1);
    this.customerLinkedList.add(customer);
    placeInLine++;
    notify();
}

synchronized Customer getNextCustomer() throws InterruptedException {
    notify();
    while (customerLinkedList.size() == 0) {
        wait();
    }
    return customerLinkedList.poll();
}

Это Касса:

    @Override
public void run() {
    try {
        while (true) {
            Customer customer = generator.getNextCustomer();
            int customerServingNumber = customer.getServingNumber();
            double customerServingTime = customer.getServingTime();
            System.out.println(cashierName + " serving " + customerServingNumber + " for " + getServingTime(customerServingTime));
            Thread.sleep(customerServingNumber * 1000);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Ответы [ 3 ]

0 голосов
/ 09 июня 2018

Как указано jspcal :

Поток Cashier завершается только после прерывания (что происходит после прямого вызова Thread.interrupt или с помощью другой функции, например ExecutorService.shutdownNow.

Хотя - да, вы можете использовать wait и notify для запуска вашей системы или Thread.interrupt() для завершения вашей нити - самый простой способ "остановить нить" Чтобы решить эту проблему, нужно изменить основной цикл Cashier с while(true) на while(condition). Это условие должно быть истинным, когда кассир принимает, и ложным, когда Cashier не принимает.

0 голосов
/ 09 июня 2018

Это сработало, но мне интересно, если это подходящее решение:

CustomerGenerator:

synchronized Customer getNextCustomer() throws InterruptedException {
    notify();
    while (customerLinkedList.size() == 0) {
        if (currentTime == openTime){
            return null;
        }
        wait();
    }
    return customerLinkedList.poll();
}

Касса:

@Override
public void run() {
    try {
        Customer customer = generator.getNextCustomer();
        while (customer != null) {
            int customerServingNumber = customer.getServingNumber();
            double customerServingTime = customer.getServingTime();
            System.out.println(cashierName + " serving " + customerServingNumber + " for " + getServingTime(customerServingTime));
            customer = null;
            Thread.sleep(customerServingNumber * 1000);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
0 голосов
/ 09 июня 2018

Поток Cashier завершается только после прерывания (что происходит после прямого вызова Thread.interrupt или с помощью другой функции, например ExecutorService.shutdownNow).Вы должны были бы организовать прерывание потока, прерывание, если установлено определенное условие, такое как логический флаг, или передачу специального пустого объекта, который сообщает потоку выйти самостоятельно.

Пока онМожно смоделировать это, используя wait и notify, как вы уже сделали, проще реализовать рабочий процесс производитель-потребитель , используя BlockingQueue.Получите ваш поток (-ы) производителя put элементов в очередь, а поток-потребитель (ы) take из очереди.Когда больше нет элементов, которые нужно создать, добавьте в очередь специальный пустой объект, который действует как сигнал для потребителя выйти или просто прервать потоки.

...