2014-05-12 07:10
原题:
Write a thread safe data structure such that there could be only one writer at a time but there could be n readers reading the data. You can consider that incrementing or decrementing a variable is an atomic operation. If more than one threads try to write simultaneously then just select one randomly and let others wait
题目:写一个线程安全的数据结构,允许单线程写,n线程读。如果多个线程尝试写数据,随机选择一个,让其他线程等待。
解法:我用信号量试着写了一个,不过不太清楚“随机选择”这个要如何表示。
代码:
1 // http://www.careercup.com/question?id=6751316000899072 2 import java.util.concurrent.Semaphore; 3 4 public class FooBar { 5 public int n = 100; 6 private Semaphore sharedSemaphore; 7 private Semaphore exclusiveSemaphore; 8 9 public FooBar(int n) { 10 // TODO Auto-generated constructor stub 11 this.n = n; 12 this.sharedSemaphore = new Semaphore(n); 13 this.exclusiveSemaphore = new Semaphore(1); 14 } 15 16 public void reader() { 17 // The reader here is not to return a value, but to perform read() 18 // action. Thus it is 'void reader()'. 19 while (exclusiveSemaphore.availablePermits() < 1) { 20 try { 21 Thread.sleep(50); 22 } catch (InterruptedException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 } 27 28 try { 29 sharedSemaphore.acquire(); 30 System.out.println("Performing read() operation."); 31 sharedSemaphore.release(); 32 } catch (InterruptedException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 } 37 38 public void writer() { 39 while (exclusiveSemaphore.availablePermits() < 1 40 && sharedSemaphore.availablePermits() < n) { 41 try { 42 Thread.sleep(50); 43 } catch (InterruptedException e) { 44 // TODO Auto-generated catch block 45 e.printStackTrace(); 46 } 47 } 48 49 try { 50 exclusiveSemaphore.acquire(); 51 System.out.println("Performing write() operation."); 52 exclusiveSemaphore.release(); 53 } catch (InterruptedException e) { 54 // TODO Auto-generated catch block 55 e.printStackTrace(); 56 } 57 } 58 59 public static void main(String[] args) { 60 FooBar fooBar = new FooBar(100); 61 62 fooBar.reader(); 63 fooBar.writer(); 64 } 65 }