Java Lock class is great for test casing
OK, so while trying to understand Oracle’s redo latching mechanisms (we have been experiencing a nightmare with log file sync since switching to a new DMX subsystem), I found that java 1.5 has a new Lock class. How cool is that?!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | import java.io.*; import java.util.concurrent.locks.*; import java.net.*; import java.util.*; class MyThread implements Runnable { static Lock l = new ReentrantLock(); static Lock lCopy = new ReentrantLock(); static Lock lAllocation = new ReentrantLock(); Thread thrd; static String logBuff[] = new String[10]; static PrintStream f; MyThread(int name){ if (f == null) { try { f = new PrintStream(new FileOutputStream("/tmp/log.log"),true); } catch(Exception e) { System.out.println("Log file does not exist"); System.exit(1); } } thrd = new Thread(this, name + ""); thrd.start(); // start the thread } private void redoAllocation(String buffVal) { for (int i = 0; i < 10; i++) { if (logBuff[i] == null) { System.out.println(i + " should be " + buffVal); logBuff[i] = buffVal; } } } private void redoWrite() { } private void writeRedo() { try { Thread.sleep(3000); lCopy.lock(); System.out.println("Got write lock"); for (int i = 0; i < 10; i++) { if (logBuff[i] == null) { f.println(i + ":" + logBuff[i]); } } lCopy.unlock(); } catch(Exception e) { System.out.println(e); } } private void redoCopy(String buffVal) { lCopy.lock(); System.out.println("Got copy lock"); redoAllocation(buffVal); System.out.println(buffVal); lCopy.unlock(); writeRedo(); } public void run(){ System.out.println(thrd.getName() + " starting."); try { boolean b = l.tryLock(10000,java.util.concurrent.TimeUnit.MILLISECONDS); if (b) { //LGWR should check this latch to see if it has work on which to wait... //What should we pass? We could just pass the value, and hold the latch for that //buffer throughout the add process. What did Oracle used to do? You could //set log_small_buffer_size (or something like that), to encourage it to do more or //less copies. System.out.println("Got the lock for " + thrd.getName()); redoCopy((new Date()).toString()); //Now, we need to get the redo allocation latch. This should allocate //space in the vector. Where should this vector live? //It should be a static part of this class of a fixed size (like log_buffer). //The allocation method should identify which block is free, and write to it. } else { System.out.println("Didn't get the lock for " + thrd.getName()); } //l.lock(); Thread.sleep(2000); l.unlock(); } catch(Exception e) {} System.out.println(thrd.getName() + " terminating."); } } class myLock { public static void main(String args[]) { for (int j = 1; j <= Integer.parseInt(args[0]); j++) { MyThread mt1 = new MyThread(j); } } } class serveLocks { static final int PORT = 6666; static int i = 0; public static void main(String[] args) throws IOException { ServerSocket s = new ServerSocket(PORT); System.out.println("Server Started"); try { while(true) { Socket socket = s.accept(); try { new MyThread(i++); } catch(Exception e) { socket.close(); } } } finally { s.close(); } } } |