Программа никогда не заканчивается, но Thread Pool утверждает, что закрывается

У меня проблема с многопоточной программой.

Мне нужно смоделировать множество людей, пытающихся забронировать один и тот же рейс одновременно, не используя замки.

Поэтому я создал ExecutorService и использовал его для объединения потоков, чтобы можно было одновременно выполнять несколько попыток.

Однако проблема в том, что программа как бы достигает конца и прямо перед тем, как распечатать все результаты, она просто сидит и работает вечно. Я попытался перейти ко всем другим классам, которые используют соединение с базой данных, и просто закрыть их вручную. Неудачно.

package dbassignment4;

   import java.util.ArrayList;
   import java.util.List;
   import java.util.concurrent.ExecutionException;
   import java.util.concurrent.ExecutorService;
   import java.util.concurrent.Future;
   import java.util.concurrent.LinkedBlockingQueue;
   import java.util.concurrent.RejectedExecutionException;
   import java.util.concurrent.ThreadPoolExecutor;
   import java.util.concurrent.TimeUnit;

   /**
    *
    * @author Vipar
    */
   public class Master{

   private static final int POOL_SIZE = 50;
   public static boolean planeIsBooked = false;
   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {

       int success = 0;
       int seatNotReserved = 0;
       int seatNotReservedByCustomerID = 0;
       int reservationTimeout = 0;
       int seatIsOccupied = 0;
       int misc = 0;

       HelperClass.clearAllBookings("CR9");
       Thread t = new Thread(new DBMonitor("CR9"));
       long start = System.nanoTime();
       //HelperClass.clearAllBookings("CR9");
       ExecutorService pool = new ThreadPoolExecutor(
               POOL_SIZE, POOL_SIZE,
               0L,
               TimeUnit.MILLISECONDS,
               new LinkedBlockingQueue<Runnable>(POOL_SIZE));
       int threadsStarted = 0;
       List<Future<Integer>> results = new ArrayList<>();
       long id = 1;
       t.start();
       while(planeIsBooked == false) {
           try {
           Future<Integer> submit = pool.submit(new UserThread(id));
           results.add(submit);
           } catch (RejectedExecutionException ex) {
               misc++;
               continue;
           }
           threadsStarted++;
           id++;
       }
       pool.shutdownNow();

       int count = 0;
       for(Future<Integer> i : results) {
           try {
               switch(i.get()) {
                   case 0:
                       // Success
                       success++;
                       break;
                   case -1:
                       // Seat is not Reserved
                       seatNotReserved++;
                       break;
                   case -2:
                       // Seat is not Reserved by Customer ID
                       seatNotReservedByCustomerID++;
                       break;
                   case -3:
                       // Reservation Timeout
                       reservationTimeout++;
                       break;
                   case -4:
                       // Seat is occupied
                       seatIsOccupied++;
                       break;
                   default:
                       misc++;
                       // Everything else fails
                       break;
               }
           } catch (ExecutionException | InterruptedException ex) {
               misc++;
           }
           count++;
           System.out.println("Processed Future Objects: " + count);
           // HERE IS WHERE IT LOOPS
       }

Вот остаток кода, который он не выполняет сразу после:

long end = System.nanoTime();
long time = end - start;
System.out.println("Threads Started: " + threadsStarted);
System.out.println("Successful Bookings: " + success);
System.out.println("Seat Not Reserved when trying to book: " + seatNotReserved);
System.out.println("Reservations that Timed out: " + reservationTimeout);
System.out.println("Reserved by another ID when trying to book: " + seatNotReservedByCustomerID);
System.out.println("Bookings that were occupied: " + seatIsOccupied);
System.out.println("Misc Errors: " + misc);
System.out.println("Execution Time (Seconds): " + (double) (time / 1000000000));
}
}

Вы можете определить проблему? Я вставил комментарий, где код перестает работать.

4 ответа

Когда planeIsBooked становиться trueПохоже, что ваш самолет забронирован, никогда не будет инициализирован в true в то время как цикл. Поэтому убедитесь, что ваш цикл не бесконечен.

Пройдите этот ответ, чтобы узнать, почему вы должны объявлять статические переменные как переменные в многопоточной среде.

Несмотря на то, что ваша статическая переменная изменчива, следующие строки опасны

while(planeIsBooked == false) {
        Future<Integer> submit = pool.submit(new UserThread(id));
   }

Считайте, что ваш заказ на рейс занимает в среднем 2 секунды. А у вас около 300 мест (предположение). Ваше поле planeIsBooked станет истинным через 600 секунд (если оно работает в одном потоке). При размере пула 50 он будет работать за 12 секунд.

С учетом вышеизложенного предположения ваш цикл будет работать 12 секунд. Теперь подумайте, сколько раз выполнялся оператор запроса на отправку? я раз. Несмотря на то, что у вас есть только 300 мест, вы можете дать appox больше минимальных миллионов запросов за 12 секунд.

Таким образом, подумайте о количестве заданий в очереди, прежде чем вызывать Shutdown now() . Это неправильный способ завершения цикла

Если вы знаете максимальный размер своего места в самолете, почему бы вам не использовать его в цикле for (возможно, это внешний параметр для цикла for вместо переменной для удержания

Пара вещей:

Сначала после звонка pool.shutdownNow(); - вы пытаетесь сразу же получить результаты. Вызов shutDownNow() не блокируется и не является точным указанием того, что пул остановлен. Для этого - вы должны позвонить pool.awaitTermination(),

Во-вторых, не ясно, что вы подразумеваете под своим комментарием -

// ЗДЕСЬ, ГДЕ ОНА ПЕТЛЯЕТ

Это находится в цикле - и, глядя на цикл - если в корпусе коммутатора возникает исключение - тогда он перейдет в ловушку - проигнорируйте его и выполните цикл. Вы проверяли наличие исключений?

Первым делом while(planeIsBooked == false) всегда оценивается как истина, потому что

planeIsBooked = false always , nowhere its initialized to true. 

так почему же ваше условие while становится ложным и выходит?

установить в то время как цикл где-то planeIsBooked = true выйти из цикла пока.

Другие вопросы по тегам