Подтвердить что ты не робот

Взаимный эксклюзивный раздел

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

Его вопрос:

"Синхронизированный блок позволяет только одному потоку входить во взаимную эксклюзивную секцию. Когда поток выходит из синхронизированного блока, синхронизированный блок не указывает какой из ожидающих потоков будет разрешен далее во взаимную эксклюзивную секцию?  Используя синхронизацию и методы, доступные в объекте, вы можете внедрять в первую очередь, первый-сервис взаимного эксклюзивного раздела? Тот, который гарантирует, что потоки взаимный эксклюзивный раздел в порядке прибытия? "

 public class Test {
   public static final Object obj = new Object();

   public void doSomething() {
     synchronized (obj) {
          // mutual exclusive section
     }
   }
 }
4b9b3361

Ответ 1

Вот простой пример:

public class FairLock {
    private int _nextNumber;
    private int _curNumber;

    public synchronized void lock() throws InterruptedException {
        int myNumber = _nextNumber++;
        while(myNumber != _curNumber) {
            wait();
        }
    }

    public synchronized void unlock() {
        _curNumber++;
        notifyAll();
    }
}

вы бы использовали его как:

public class Example {
  private final FairLock _lock = new FairLock();

  public void doSomething() {
    _lock.lock();
    try {
      // do something mutually exclusive here ...
    } finally {
      _lock.unlock();
    }
  }
}

(обратите внимание, что это не относится к ситуации, когда вызывающий объект lock() получает прерванное исключение!)

Ответ 2

то, что они задавали, - это справедливый мьютекс

создать очередь FIFO объектов блокировки, которые нажимаются на нее потоками, ожидающими блокировки, а затем ждать на нем (все это, кроме ожидания в синхронизированном блоке на отдельной блокировке)

затем, когда блокировка освобождается, объект выскользнул из очереди, и поток, ожидающий его, проснулся (также синхронизирован в той же блокировке для добавления объектов)

Ответ 3

Вы можете использовать ReentrantLock, где параметр справедливости установлен в значение true. Тогда следующий поток, который будет обслуживаться, будет потоком, ожидающим самое длинное время, то есть тот, который прибыл первым.

Ответ 4

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

 public class Test {
    public static final Object obj = new Object();
    unsigned int count = 0;  // unsigned global int
    unsigned int next  = 0;  // unsigned global int

    public void doSomething() {
       unsigned int my_number;  // my ticket number

       // the critical section is small. Just pick your ticket number. Guarantee FIFO
       synchronized (obj) { my_number = count ++; } 

       // busy waiting
       while (next != my_number);

       // mutual exclusion

       next++;  // only one thread will modify this global variable
    }
 }

Недостатком этого ответа является ожидание, которое будет потреблять процессорное время.

Ответ 5

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