Skip to content

Instantly share code, notes, and snippets.

@takaheraw
Created October 24, 2015 01:56
Show Gist options
  • Save takaheraw/f4defe415005b729895c to your computer and use it in GitHub Desktop.
Save takaheraw/f4defe415005b729895c to your computer and use it in GitHub Desktop.
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