Created
October 24, 2015 01:56
-
-
Save takaheraw/f4defe415005b729895c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Book { | |
let author:String | |
let title:String | |
let stockNumber:Int | |
var reader:String? | |
var checkCount = 0 | |
init(author:String, title:String, stock:Int) { | |
self.author = author | |
self.title = title | |
self.stockNumber = stock | |
} | |
} | |
class Pool<T> { | |
private var data = [T]() | |
private let arrayQ = dispatch_queue_create("arrayQ", DISPATCH_QUEUE_SERIAL) | |
private let semaphore:dispatch_semaphore_t | |
init(items:[T]) { | |
data.reserveCapacity(data.count) | |
for item in items { | |
data.append(item) | |
} | |
semaphore = dispatch_semaphore_create(items.count) | |
} | |
func getFromPool() -> T? { | |
var result:T? | |
if (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) == 0) { | |
dispatch_sync(arrayQ, {() in | |
result = self.data.removeAtIndex(0) | |
}) | |
} | |
return result | |
} | |
func returnToPool(item:T) { | |
dispatch_async(arrayQ, {() in | |
self.data.append(item) | |
dispatch_semaphore_signal(self.semaphore) | |
}) | |
} | |
} | |
final class Library { | |
private var books:[Book] = [] | |
private let pool:Pool<Book> | |
private init(stockLevel:Int) { | |
for count in 1...stockLevel { | |
books.append(Book(author: "Dick", title: "Hard", stock: count)) | |
} | |
pool = Pool<Book>(items:books) | |
} | |
private class var singleton:Library { | |
struct SingletonWrapper { | |
static let singleton = Library(stockLevel: 2) | |
} | |
return SingletonWrapper.singleton | |
} | |
class func checkoutBook(reader:String) -> Book? { | |
let book = singleton.pool.getFromPool() | |
book?.reader = reader | |
book?.checkCount++ | |
return book | |
} | |
class func returnBook(book:Book) { | |
book.reader = nil | |
singleton.pool.returnToPool(book) | |
} | |
class func printReport() { | |
for book in singleton.books { | |
print("...Book#\(book.stockNumber)...") | |
print("Checked out \(book.checkCount) times") | |
if book.reader != nil { | |
print("Checked out to \(book.reader!)") | |
} else { | |
print("In stock") | |
} | |
} | |
} | |
} | |
var queue = dispatch_queue_create("workQ", DISPATCH_QUEUE_CONCURRENT) | |
var group = dispatch_group_create() | |
print("Start") | |
for i in 1...20 { | |
dispatch_group_async(group, queue, {() in | |
var book = Library.checkoutBook("reader#\(i)") | |
if (book != nil) { | |
NSThread.sleepForTimeInterval(Double(rand() % 2)) | |
Library.returnBook(book!) | |
} | |
}) | |
} | |
dispatch_group_wait(group, DISPATCH_TIME_FOREVER) | |
print("All blocks complete") | |
Library.printReport() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment