2011-12-24 5 views
1

Скажите, что есть книжная библиотека. Люди могут брать книги и возвращать книги. В каждой книге есть одна или несколько копий.Как реализовать библиотеку книг с многопоточной программой?

Предположим, что:
1. Если человек приходит в библиотеку со списком книг, он не покинет библиотеку без всех книг. 2. Невозможно, чтобы в каком-то списке заемщиков были книги, библиотека которых не имеет хотя бы одного экземпляра.

Мы согласны с тем, что заемщики представлены потоками.

я могу думать только один вариант для его реализации:

public synchronized void borrowBooks(final ArrayList<Item> booksList) 
{ 
    try { 
     while (!areBooksPresent(booksList)) { 
      this.wait(); 
     } 
    } catch (InterruptedException e) {} 

    for (Book book : booksList) { 
     Book libraryBook = findBook(book); 
     /* Decrement the book's amount in the library */ 
     libraryBook.decAmount(); 
    } 
} 


public synchronized void returnBooks(final ArrayList<Item> booksList) 
{ 
    for (Book book : booksList) { 
     Book libraryBook = findBook(book); 
     /* increment the book's amount in the library */ 
     libraryBook.incAmount(); 
     /* Notify to all awaiting threads that the monitor is freed */ 
     this.notifyAll(); 
    } 
} 

Как вы можете видеть, как поток начинает занимать свои книги, вся библиотека закрыта, и никакой другой поток не может занимать в то же время. Мы также гарантируем, что в цикле for для заимствования книг невозможно, чтобы книги не было.

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

Другие альтернативы, по-видимому, вызывают взаимоблокировки.

У вас есть предложения для более параллельного решения, которое также безопасно и имеет жизнестойкость?

ответ

1

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

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

Это может, однако, заставлять некоторых заемщиков ждать вечно. Чтобы избежать этого, используйте специальный алгоритм приоритета. Держите очередь заемщиков в порядке прибытия. Поместите новых заемщиков на заднюю часть линии. Затем просто реализуйте одно правило - если есть какая-либо книга, которой нужен главный заемщик, ее может взять только главный заемщик.

Это даст вам один специальный случай, с которым вам придется обращаться: заемщик не является главным заемщиком, все необходимые ему книги доступны, но он не может их принять, потому что одна из книг нужна головному заемщику. В этом случае у вас есть специальный «главный заемщик», который может ждать заемщик. Когда заемщик получает все свои книги, проверьте, был ли он основным заемщиком, и если так разблокировать все потоки, ожидающие этого события.

Любой заемщик, в любое время, имеет некоторое конечное число заемщиков перед ним. Это число не может увеличиться. И это уменьшится, потому что один из заемщиков впереди вас (главный) имеет абсолютный приоритет, и каждая книга возвращается в конце концов. Заемщик никогда не держит книгу, пока она ждет других книг. Так что это должно быть беззаконным.

+0

Очередь для каждой книги? –

+0

Вам не нужна очередь для каждой книги. Но вы (потенциально) нуждаетесь в событии для каждой книги, которая была заимствована, которую ждет поток. –

Смежные вопросы