Hello all!

I'm writing a simple program that consists of 10 threads and a library of 5 books. Each thread checks to see if the library has any books to check out, and enters a FIFO queue if the library is empty. Otherwise the thread checks out the first book in the library, reads it (sleeps for a random amount of time) then enters a queue to return the book to the library.

After every checkout, my program prints out which thread checked out what book, and also what books remain in the library. I've ran the program a couple of times and have noticed that multiple threads have been checking out the same book, even though the book should be removed from the queue. I have code and output below. Any suggestions would be much appreciated!

The class Library contains a Queue called books which is a 5 element LinkedList, having values 1-5.

Output:public class PatronThread extends Thread { public Library library = new Library(); public boolean taken = false; public Queue<Thread> tQueue = new LinkedList<Thread>(); public Queue<Thread> t2Queue = new LinkedList<Thread>(); public PatronThread(String name) { super(name); } @Override public void run() { Thread t = Thread.currentThread(); int maxBooks = 4, currentBooks = 0; int current = 0; while(currentBooks < maxBooks){ try{Thread.sleep( (int) Math.random() * 1000); } catch (InterruptedException e){ } //Checkout book from library if(library.books.size() == 0){ System.err.println(t.getName() + " entering FIFO queue to get a book. " + "Library currently has " + library.books + "\n"); tQueue.add(t); } else{ t2Queue.add(t); synchronized(this){ current = library.books.remove(); System.err.println(t.getName() + " got book " + current + ". Library now has " + library.books + "\n"); } //Reading Book try{Thread.sleep((int) Math.random() * 1000); } catch (InterruptedException e) { } //Returning book library.books.add(current); System.err.println(t2Queue.remove().getName() + " entering FIFO to return book " + current + ". Library currently has books \n" + library.books + "\n"); } currentBooks++; } } }

t1 got book 1. Library now has [2, 3, 4, 5]

t2 got book 1. Library now has [2, 3, 4, 5]

t3 got book 1. Library now has [2, 3, 4, 5]

t6 got book 1. Library now has [2, 3, 4, 5]

t4 got book 1. Library now has [2, 3, 4, 5]

t10 got book 1. Library now has [2, 3, 4, 5]

t8 got book 1. Library now has [2, 3, 4, 5]

t2 entering FIFO to return book 1. Library currently has books

[2, 3, 4, 5, 1]

t9 got book 1. Library now has [2, 3, 4, 5]

t1 entering FIFO to return book 1. Library currently has books

[2, 3, 4, 5, 1]

t2 got book 2. Library now has [3, 4, 5, 1]

t9 entering FIFO to return book 1. Library currently has books

[2, 3, 4, 5, 1]