src/org/objectweb/cjdbc/controller/scheduler/schema/TransactionExclusiveLock.java

説明を見る。
00001 00025 package org.objectweb.cjdbc.controller.scheduler.schema; 00026 00027 import java.util.ArrayList; 00028 00029 import org.objectweb.cjdbc.common.sql.AbstractRequest; 00030 00040 public class TransactionExclusiveLock 00041 { 00042 private boolean isLocked = false; 00043 00045 private long locker; 00046 00048 private ArrayList waitingList = new ArrayList(); 00049 00054 private class WaitingListElement 00055 { 00057 Thread thread; 00058 00060 long transactionId; 00061 00068 WaitingListElement(Thread thread, long transactionId) 00069 { 00070 this.thread = thread; 00071 this.transactionId = transactionId; 00072 } 00073 00079 public long getTransactionId() 00080 { 00081 return transactionId; 00082 } 00083 00089 public Thread getThread() 00090 { 00091 return thread; 00092 } 00093 } 00094 00107 public boolean acquire(AbstractRequest request) 00108 { 00109 long tid = request.getTransactionId(); 00110 00111 synchronized (Thread.currentThread()) 00112 { 00113 WaitingListElement wle = null; 00114 synchronized (this) 00115 { 00116 if (!isLocked) 00117 { // Lock is free, take it 00118 locker = tid; 00119 isLocked = true; 00120 return true; 00121 } 00122 else 00123 { 00124 if ((!request.isAutoCommit()) && (locker == tid)) 00125 return true; // We already have the lock 00126 else 00127 { // Wait for the lock 00128 wle = new WaitingListElement(Thread.currentThread(), tid); 00129 waitingList.add(wle); 00130 } 00131 } 00132 } 00133 // At this point, we have to wait for the lock. 00134 try 00135 { 00136 int timeout = request.getTimeout(); 00137 if (timeout == 0) 00138 { 00139 Thread.currentThread().wait(); // No timeout 00140 // Note: isLocked and locker are already set. 00141 return true; 00142 } 00143 else 00144 { // Wait with timeout 00145 long start = System.currentTimeMillis(); 00146 // Convert seconds to milliseconds for wait call 00147 long lTimeout = timeout * 1000; 00148 Thread.currentThread().wait(lTimeout); 00149 long end = System.currentTimeMillis(); 00150 int remaining = (int) (lTimeout - (end - start)); 00151 if (remaining > 0) 00152 { // Ok 00153 request.setTimeout(remaining); 00154 // Note: isLocked and locker are already set. 00155 return true; 00156 } 00157 else 00158 { // Too late, remove ourselves from the waiting list 00159 synchronized (this) 00160 { 00161 int idx = waitingList.indexOf(wle); 00162 if (idx == -1) 00163 // We got the lock before being able to acquire the lock on 00164 // this. Give the lock to the next one. 00165 release(); 00166 else 00167 waitingList.remove(idx); 00168 } 00169 return false; 00170 } 00171 } 00172 } 00173 catch (InterruptedException ie) 00174 { 00175 synchronized (this) 00176 { // Something wrong happened, remove ourselves from the waiting list 00177 waitingList.remove(Thread.currentThread()); 00178 } 00179 return false; 00180 } 00181 } 00182 } 00183 00189 public synchronized void release() 00190 { 00191 while (!waitingList.isEmpty()) 00192 { 00193 // Wake up the first waiting thread and update locker transaction id 00194 WaitingListElement e = (WaitingListElement) waitingList.remove(0); 00195 Thread thread = e.getThread(); 00196 locker = e.getTransactionId(); 00197 synchronized (thread) 00198 { 00199 thread.notify(); 00200 // isLocked remains true 00201 return; 00202 } 00203 } 00204 isLocked = false; 00205 } 00206 00212 public boolean isLocked() 00213 { 00214 return isLocked; 00215 } 00216 00223 public long getLocker() 00224 { 00225 return locker; 00226 } 00227 00233 public ArrayList getWaitingList() 00234 { 00235 return waitingList; 00236 } 00237 00245 public synchronized boolean isWaiting(long transactionId) 00246 { 00247 WaitingListElement e; 00248 int size = waitingList.size(); 00249 for (int i = 0; i < size; i++) 00250 { 00251 e = (WaitingListElement) waitingList.get(i); 00252 if (e.getTransactionId() == transactionId) 00253 return true; 00254 } 00255 return false; 00256 } 00257 }

CJDBCversion1.0.4に対してTue Oct 12 15:16:04 2004に生成されました。 doxygen 1.3.8