Java Threads занята ожиданием

Привет, я делаю проект, и я достиг той части, где я очень застрял. Я пытался найти способы научиться писать цикл while для занятого ожидания, но я ничего не нашел, и мой код просто работает как бесконечный цикл. Может ли кто-нибудь помочь мне объяснить, как должен работать занятый цикл ожидания и помочь мне выйти из этого бесконечного цикла?

Проект хочет, чтобы произошло следующее: утром, после того, как ученик проснется (это займет произвольное время), он отправится в ванную, чтобы подготовиться к новому учебному дню. Если ванная уже занята, учащийся делает перерыв (используйте yield()), и позже он будет ждать (использует занятое ожидание), пока ванная не станет доступной. Студенты будут использовать ванную в порядке поступления заявок (вы можете использовать логический массив / вектор, чтобы они были освобождены по порядку).

 public class Student implements Runnable 
    {
        private Random rn = new Random();
        private String threadNum;
        private volatile boolean bathroomFull = false;
        private static long time = System.currentTimeMillis();
        private Thread t;


    public Student(String studentID) 
    {
      threadNum = studentID;

      t = new Thread(this, "Student Thread #"+threadNum);
      System.out.println("thread created = " + t);
      // this will call run() function
      t.start();
   }

   public void run() 
   {
       int waitTime = rn.nextInt(4000 - 2000 + 1)+2000;

        System.out.println( "the current time is " + (System.currentTimeMillis() - time) + "and the wait time is: " +waitTime );

         //Student wakes up after random time
        while((System.currentTimeMillis()-time) < waitTime)
       {
          // System.out.println("the remaining sleep time is " + (System.currentTimeMillis()-time));
            ;
       }

      int a = rn.nextInt(4000 - 2000 + 1)+2000;
      try 
      {
          //System.out.println("I'm going to sleep for " +a + " milliseconds");
        Thread.sleep(a);
      } 
      catch (InterruptedException e) 
      {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      //this is the busy wait loop where is the bathroom is full then a thread will yield until it is available
    int l = rn.nextInt(10 - 1)+1;
  bathroomFull = true;

      while(bathroomFull)
        {
          for(int j = 0; j < l; j++)
          {
              System.out.println("i am in the bathroom for " + l + "minutes " + Thread.currentThread());
          }
          Thread.yield();
          bathroomFull = false;
          //exitBathroom();

        }
    bathroomFull = true;

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

 public static void main(String args[]) 
   {
       int numberOfStudents;
       numberOfStudents = Integer.parseInt(JOptionPane.showInputDialog("How many students are there in the university? "));
      // System.out.println("there are " + numberOfStudents);

       for(int i = 0; i < numberOfStudents; i++)
       {   
           new Student(String.valueOf(i+1));
       }
          new Teacher();
   }

1 ответ

Решение

Вот рабочий пример занятого ожидания. Он использует AtomicBoolean, чтобы указать, занята ли ванная или нет. Атомарные операции выполняются за один шаг, это важно для обеспечения безопасности потоков. Мы могли бы также использовать нормальное логическое значение и написать compareAndSet сами:

private static synchronized boolean compareAndSet(boolean expected, boolean value) {
    if (occupied == expected) { // (1)
        occupied = value; // (2)
        return true;
    } else {
        return false;
    }
}

Это эквивалент (для этого примера) реализации Java. synchronized в противном случае было бы возможно, чтобы два потока успешно прошли тест в (1) до (2) был выполнен (потому что эти две операции не атомарные), а затем два человека пошли бы в ванную вместе...

import java.util.concurrent.atomic.AtomicBoolean;

public class Student extends Thread {

    // note the static: there is only one bathroom for all students
    private static AtomicBoolean occupied = new AtomicBoolean(false);

    private String name;

    public Student(String name) {
        this.name = name;
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            System.out.println(name + " wet his/her pants");
        }
    }

    @Override
    public void run() {
        int r = (int)(Math.random() * 5000);
        System.out.println(name + " sleeps for " + r + " ms");
        sleep(r);
        System.out.println(name + " goes to bathroom");
        // ***** busy wait *****
        while (!occupied.compareAndSet(false, true)) {
            System.out.println(name + " takes a break");
            Thread.yield();
            sleep(1000);
        }
        // ***** end (in bathroom) *****
        System.out.println(name + " is in the bathroom");
        sleep(1000);
        occupied.set(false);
        System.out.println(name + " goes to university");
    }

    public static void main(String[] args) {
        new Student("Bob").start();
        new Student("Alice").start();
        new Student("Peter").start();
        new Student("Marcia").start();
        new Student("Desmond").start();
        new Student("Sophia").start();
    }

}

Возможный вывод:

Боб спит в течение 2128 мс
Марсия спит 3357 мс
Алиса спит 1289 мс
Питер спит 820 мс
Десмонд спит в течение 1878 мс
София спит 2274 мс
Питер идет в ванную
Питер в ванной
Алиса идет в ванную
Алиса отдыхает
Питер идет в университет
Десмонд идет в ванную
Десмонд в ванной
Боб идет в ванную
Боб делает перерыв
София идет в ванную
София отдыхает
Алиса отдыхает
Десмонд учится в университете
Боб в ванной
София отдыхает
Алиса отдыхает
Марсия идет в ванную
Марсия отдыхает
Боб ходит в университет
София в ванной
Алиса отдыхает
Марсия отдыхает
София идет в университет
Алиса в ванной
Марсия отдыхает
Алиса ходит в университет
Марсия в ванной
Марсия идет в университет

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