2015-04-24 6 views
1

У меня возникают проблемы с циклом while, который будет запускать систему меню.Пока цикл цикла Java завершается до тех пор, пока не завершены потоки

Это код, который я использую. Каждый поток, или Заемщик, выполняет задачи одновременно с командами sleep() в каждом. Проблема, которую я теперь имею это когда каждый Заемщик Thread запускается Е.Г.

for(int i = 0 ;i < borrowCount; i++) { 
    model.getBorrowers().add(new Borrower(i+1,model.getLibrary(),model.runs)); 

model.librarian().start(); 

for(Borrower b : model.getBorrowers()) { 
    b.start(); 
} 

Заемщики начинают, однако, из-за сна() команды будучи вовлеченным цикл Хотя возвращается вокруг и перепечатывает меню в выходе из Потоки.

Есть ли способ убедиться, что цикл While только возвращается назад, как только все потоки завершены?

Ниже приведен код, я использую:

**** отредактированные и обновленный код *****

package model; 

import java.util.ArrayList; 
import java.util.Scanner; 

public class LibraryModel implements Runnable{ 
    Library library = new Library(); 
    Librarian librarian; 
    ArrayList<Borrower> BorrowArray = new ArrayList<Borrower>(); 
    int runs = 0; 
    Boolean isActive = true; 

public LibraryModel() { 
    library.AddBooks(); 
} 

public static void main(String[]args) 
{ 
    int borrowCount = 0; 
    System.out.println("Welcome to the Library Simulator\n"); 


    LibraryModel model = new LibraryModel(); 
    Scanner sc = new Scanner(System.in); 
    String a = sc.next(); 
    char quit = 'y'; 

    while(quit != 'q') { 

    String a = sc.next(); 
    System.out.println("\n[S = start, A = About, Q = quit]"); 

    switch (a) { 

     case "S": 
      System.out.println("Please enter the number of Borrowers\n"); 
      borrowCount = sc.nextInt(); 
      System.out.println("Please enter how many runs the Program will run"); 
      model.runs = sc.nextInt(); 

      model.librarian = new Librarian(model.library,model.runs); 

      for(int i = 0 ;i < borrowCount; i++) { 
       model.getBorrowers().add(new Borrower(i+1,model.getLibrary(),model.runs)); 
       } 
       model.librarian().start(); 

       for(Borrower b : model.getBorrowers()) { 
        b.start(); 
       } 
     break; 


     case "A": 
     break; 

     case "Q" : 
      quit = 'q'; 
     break; 


     default : 
      System.out.println("Incorrect Entry, please enter a correct"); 
     break; 
    } 
} 

Запрошенный код с участием Заемщика:

package model; 

public class Borrower extends Thread { 

private int noOfBooks; 
private Set<Book> BooksBorrowed; 
private Set<Integer> booksRequested; 
private int id; 
private int runs; 
private Library library; 
private Random randSleep = new Random(); 

public Borrower(int id, Library library, int runs) { 

    this.library = library; 
    this.id = id; 
    this.runs = runs; 
    noOfBooks = 1; 

    } 

public Borrower(){} 

public String getLoans() { 
    String output = ""; 
    for(Book b : BooksBorrowed) { 
     output +=" "+b.getBookId()+" "; 
    } 
    return output; 
} 

public void run() 
{ 
    try { 
     Initialize(); 

     for(int i = 0; i < runs; i++) { 
      RequestBooks(); 
      ReturnBooks(); 
     } 

    } finally {} 
} 

public synchronized void Initialize() { 

    int min = 1; 
    int max = 10; 
    Random r = new Random(); 
    noOfBooks = r.nextInt(max - min + 1) + min; 

    System.out.println("--------------------------"); 
    System.out.println("Borrower "+id+" Starting"); 

    notifyAll(); 
} 

public synchronized void RequestBooks() { 

    Random r2 = new Random(); 
    Book temp = null; 

    ArrayList<Book>books = new ArrayList<Book>(library.getBooks()); 
    ArrayList<Integer>Chosen = new ArrayList<Integer>(); 

    for(int i = 0; i < noOfBooks; i++){ 
     int index = r2.nextInt(books.size()); 
     temp = books.get(index); 
     int tempId = temp.getBookId(); 
     Chosen.add(tempId); 
    } 
    System.out.println("--------------------------"); 
    System.out.println("\nBorrower "+id+" requests " +noOfBooks+" Books from Library "); 

    booksRequested = new HashSet<Integer>(Chosen); 

    String requestedBooks = ""; 

    for(Integer bookid : Chosen) { 
     requestedBooks = requestedBooks+bookid+" "; 
     booksRequested.add(bookid); 

    } 
    System.out.println("Borrower "+id+" request Books: "+requestedBooks); 

    BooksBorrowed = library.RQST(id,booksRequested); 
    ArrayList<Book> chosenBooks = new ArrayList<Book>(); 
    chosenBooks.addAll(BooksBorrowed); 

    System.out.println("Books requested by Borrower "+id+" : "+requestedBooks+"\n"); 

    String receivedBooks = ""; 
    Book[]BookArray = BooksBorrowed.toArray(new Book[BooksBorrowed.size()]); 
    for(Book b : BookArray) { 
     receivedBooks = receivedBooks+b.getBookId()+" "; 
    } 

    System.out.println("Borrower "+id+" Books recieved :"+receivedBooks); 
    System.out.println("--------------------------"); 
    notifyAll(); 

} 

public synchronized void ReturnBooks() { 
    Set<Integer> BooksReturned; 
    ArrayList<Integer> returningBooks = new ArrayList<Integer>(); 
    String returnedBooks = ""; 
    ArrayList<Book> borrowed = new ArrayList<Book>(BooksBorrowed); 

    for (Book b : borrowed) { 
     returningBooks.add(b.getBookId()); 
     returnedBooks = returnedBooks+b.getBookId()+" "; 
    } 

    BooksReturned = new HashSet<Integer>(returningBooks); 

    library.RTRN(BooksReturned); 
    System.out.println("\nBorrower "+id+" returned books to library: "+returnedBooks+"\n"); 
} 

}

+0

Я думаю, вы можете https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html нити, но более высокие абстракции() может Исполнители быть лучшей альтернативой. –

ответ

0

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

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

ExecutorService threadPool = Executors.newCachedThreadPool(); 
threadPool.submit(librarian); 
for (Borrower b : borrowers) { 
    threadPool.submit(b); 
} 
threadPool.shutdown(); 
threadPool.awaitTermination(1, TimeUnit.DAYS); // do this in a loop or error if it hasnt finished? 
+0

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

+0

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

+0

дал это, и проблема все еще присутствует –