Index: java/engine/org/apache/derby/impl/services/locks/LockSet.java
===================================================================
--- java/engine/org/apache/derby/impl/services/locks/LockSet.java	(revision 431605)
+++ java/engine/org/apache/derby/impl/services/locks/LockSet.java	(working copy)
@@ -65,13 +65,15 @@
 	@see LockControl
 */
 
-public final class LockSet extends Hashtable
+public final class LockSet
 {
 	/*
 	** Fields
 	*/
 	private final SinglePool factory;
 
+	private final Hashtable[] tables;
+
 	/**
 		Timeout for deadlocks, in ms.
 		<BR>
@@ -101,6 +103,10 @@
 	protected LockSet(SinglePool factory) {
 		super();
 		this.factory = factory;
+		tables = new Hashtable[16];
+		for (int i = 0; i < tables.length; i++) {
+			tables[i] = new Hashtable();
+		}
 	}
 
 
@@ -127,9 +133,12 @@
 		if (SanityManager.DEBUG) {
 
 			if (SanityManager.DEBUG_ON("memoryLeakTrace")) {
-
-				if (size() > 1000)
-					System.out.println("memoryLeakTrace:LockSet: " + size());
+				int size = 0;
+				for (int i = 0; i < tables.length; i++) {
+					size += tables[i].size();
+				}
+				if (size > 1000)
+					System.out.println("memoryLeakTrace:LockSet: " + size);
 			}
 		}
 
@@ -138,7 +147,8 @@
 		Lock lockItem;
         String  lockDebug = null;
 
-		synchronized (this) {
+		Hashtable table = getTable(ref);
+		synchronized (table) {
 
 			gc = getControl(ref);
 
@@ -149,14 +159,14 @@
 
 				gl.grant();
 
-				put(ref, gl);
+				table.put(ref, gl);
 
 				return gl;
 			}
 
 			control = gc.getLockControl();
 			if (control != gc) {
-				put(ref, control);
+				table.put(ref, control);
 			}
 			
 
@@ -292,7 +302,9 @@
                     Enumeration timeoutLockTable = null;
                     long currentTime = 0;
         
-                    synchronized (this) {
+					// assert nextWaitingLock == null ||
+					//    table == getTable(nextWaitingLock.getLockable())
+                    synchronized (table) {
 
                         if (control.isGrantable(
                                 control.firstWaiter() == waitingLock,
@@ -526,7 +538,8 @@
 		boolean tryGrant = false;
 		ActiveLock nextGrant = null;
 
-		synchronized (this) {
+		Hashtable table = getTable(item.getLockable());
+		synchronized (table) {
 
 			Control control = getControl(item.getLockable());
 			
@@ -578,11 +591,11 @@
 			if (mayBeEmpty) {
 				if (control.isEmpty()) {
 					// no-one granted, no-one waiting, remove lock control
-					remove(control.getLockable());
+					table.remove(control.getLockable());
 				}
 				return;
 			}
-		} // synchronized (this)
+		} // synchronized (table)
 
 		if (tryGrant && (nextGrant != null)) {
 			nextGrant.wakeUp(Constants.WAITING_LOCK_GRANT);
@@ -617,14 +630,15 @@
             String str = new String();
 
             int i = 0;
-            for (Enumeration e = this.elements(); 
-                 e.hasMoreElements();
-                 i++)
-            {
-                str += "\n  lock[" + i + "]: " + 
-                    DiagnosticUtil.toDiagString(e.nextElement());
-            }
-
+			for (int t = 0; t < tables.length; t++) {
+                for (Enumeration e = tables[t].elements(); 
+                     e.hasMoreElements();
+                     i++)
+                {
+                    str += "\n  lock[" + i + "]: " + 
+                        DiagnosticUtil.toDiagString(e.nextElement());
+                }
+			}
             return(str);
         }
         else
@@ -638,18 +652,28 @@
 	 * make a shallow clone of myself and my lock controls
 	 */
 	/* package */
-	synchronized LockSet shallowClone()
+	LockSet shallowClone()
 	{
-		LockSet clone = new LockSet(factory);
+		return shallowCloneHelper(new LockSet(factory), 0);
+	}
 
-		for (Enumeration e = keys(); e.hasMoreElements(); )
-		{
-			Lockable lockable = (Lockable)e.nextElement();
-			Control control = getControl(lockable);
-
-			clone.put(lockable, control.shallowClone());
+	private LockSet shallowCloneHelper(LockSet clone, int level) {
+		if (level < tables.length) {
+			Hashtable table = tables[level];
+			synchronized (table) {
+				return shallowCloneHelper(clone, level + 1);
+			}
 		}
-
+		// all tables are locked, copy them
+		for (int i = 0; i < level; i++) {
+			Hashtable table = tables[i];
+			for (Enumeration e = table.keys(); e.hasMoreElements(); ) {
+				Lockable lockable = (Lockable) e.nextElement();
+				Control control = (Control) table.get(lockable);
+				Hashtable t = clone.getTable(lockable);
+				t.put(lockable, control.shallowClone());
+			}
+		}
 		return clone;
 	}
 //EXCLUDE-END-lockdiag- 
@@ -677,6 +701,14 @@
 	}
 
 	public final Control getControl(Lockable ref) {
-		return (Control) get(ref);
+		return (Control) getTable(ref).get(ref);
 	}
+
+	final Hashtable getTable(Lockable ref) {
+		return tables[(ref.hashCode() & 0x7fffffff) % tables.length];
+	}
+
+	final Hashtable[] getTables() {
+		return tables;
+	}
 }
Index: java/engine/org/apache/derby/impl/services/locks/LockSpace.java
===================================================================
--- java/engine/org/apache/derby/impl/services/locks/LockSpace.java	(revision 431605)
+++ java/engine/org/apache/derby/impl/services/locks/LockSpace.java	(working copy)
@@ -256,7 +256,7 @@
 			return 0;
 
 		Lock lockInGroup;
-		synchronized (lset) {
+		synchronized (lset.getTable(ref)) {
 			Control control = lset.getControl(ref);
 			if (control == null)
 				return 0;
Index: java/engine/org/apache/derby/impl/services/locks/Deadlock.java
===================================================================
--- java/engine/org/apache/derby/impl/services/locks/Deadlock.java	(revision 431605)
+++ java/engine/org/apache/derby/impl/services/locks/Deadlock.java	(working copy)
@@ -182,6 +182,7 @@
 
 	private static Hashtable getWaiters(LockSet set) {
 
+		/*
 		Hashtable waiters = new Hashtable(set.size() * 2);
 
 		for (Enumeration e = set.elements(); e.hasMoreElements(); ) {
@@ -190,7 +191,16 @@
 
 			control.addWaiters(waiters);
 		}
+		*/
 
+		Hashtable waiters = new Hashtable();
+		Hashtable[] tables = set.getTables();
+		for (int i = 0; i < tables.length; i++) {
+			for (Enumeration e = tables[i].elements(); e.hasMoreElements(); ) {
+				Control control = (Control) e.nextElement();
+				control.addWaiters(waiters);
+			}
+		}
 		return waiters;
 	}
 
@@ -216,7 +226,8 @@
 				break;
 			}
 
-			LockSpace ls = (LockSpace) factory.get(space);
+			Hashtable spaceTable = factory.getSpaceTable(space);
+			LockSpace ls = (LockSpace) spaceTable.get(space);
 			if (ls == null) {
 				// space only holds latches, pick as victim
 				victim = space;
Index: java/engine/org/apache/derby/impl/services/locks/SinglePool.java
===================================================================
--- java/engine/org/apache/derby/impl/services/locks/SinglePool.java	(revision 431605)
+++ java/engine/org/apache/derby/impl/services/locks/SinglePool.java	(working copy)
@@ -62,9 +62,7 @@
 	MT - Mutable - Container Object : Thread Aware
 */
 
-public class SinglePool extends Hashtable
-	implements  LockFactory
-{
+public class SinglePool implements LockFactory {
 	/**
 		The complete set of locks in the system
 
@@ -92,6 +90,7 @@
         safe.
 		
 	*/
+	private final Hashtable[] spaces;
 
 	/**
 		True if all deadlocks errors should be logged.
@@ -100,8 +99,18 @@
 
 	public SinglePool() {
 		lockTable = new LockSet(this);
+		spaces = new Hashtable[16];
+		for (int i = 0; i < spaces.length; i++) {
+			spaces[i] = new Hashtable();
+		}
 	}
 
+	final Hashtable getSpaceTable(Object compatabilitySpace) {
+		int hash = compatabilitySpace.hashCode();
+		int index = (hash & 0x7fffffff) % spaces.length;
+		return spaces[index];
+	}
+
 	/*
 	** Methods of LockFactory
 	*/
@@ -192,12 +201,13 @@
 		}
 
 		// find the space and atomically add lock to required group
-		synchronized (this) {
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		synchronized (space) {
 
-			LockSpace ls = (LockSpace) get(compatabilitySpace);
+			LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 			if (ls == null)	{
-				 ls = new LockSpace(this, compatabilitySpace);
-				 put(compatabilitySpace, ls);
+				 ls = new LockSpace(space, compatabilitySpace);
+				 space.put(compatabilitySpace, ls);
 			}
 
 			// we hold the spaces monitor while adding the lock to close 
@@ -267,7 +277,8 @@
 			}
 		}
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return 0;
 
@@ -300,7 +311,8 @@
 			}
 		}
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return;
 
@@ -315,7 +327,8 @@
 			}
 		}
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return;
 
@@ -349,7 +362,8 @@
 			}
 		}
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return;
 
@@ -380,7 +394,8 @@
 	*/
 	public boolean areLocksHeld(Object compatabilitySpace, Object group) {
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return false;
 
@@ -401,7 +416,8 @@
 		@see LockFactory#areLocksHeld
 	*/
 	public boolean areLocksHeld(Object compatabilitySpace) {
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return false;
 		return !ls.isEmpty();
@@ -437,9 +453,9 @@
 		// If the caller wants to wait and the lock cannot
 		// be granted then we do the slow join the queue and
 		// release the lock method.
-		synchronized (lockTable) {
+		synchronized (lockTable.getTable(ref)) {
 
-			Control control = (Control) lockTable.get(ref);
+			Control control = lockTable.getControl(ref);
 			if (control == null) {
 				return true;
 			}
@@ -475,30 +491,32 @@
 
 	public boolean isLockHeld(Object compatabilitySpace, Object group, Lockable ref, Object qualifier) {
 
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return false;
 
 		return ls.isLockHeld(group, ref, qualifier);
 	}
 
-	public synchronized void setLimit(Object compatabilitySpace, Object group, int limit, Limit callback) {
-
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
-		if (ls == null)	{
-			 ls = new LockSpace(this, compatabilitySpace);
-			 put(compatabilitySpace, ls);
+	public void setLimit(Object compatabilitySpace, Object group, int limit, Limit callback) {
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		synchronized (space) {
+			LockSpace ls = (LockSpace) space.get(compatabilitySpace);
+			if (ls == null)	{
+				ls = new LockSpace(space, compatabilitySpace);
+				space.put(compatabilitySpace, ls);
+			}
+			ls.setLimit(group, limit, callback);
 		}
-
-		ls.setLimit(group, limit, callback);
-		
 	}
 
 	/**
 		Clear a limit set by setLimit.
 	*/
 	public void clearLimit(Object compatabilitySpace, Object group) {
-		LockSpace ls = (LockSpace) get(compatabilitySpace);
+		Hashtable space = getSpaceTable(compatabilitySpace);
+		LockSpace ls = (LockSpace) space.get(compatabilitySpace);
 		if (ls == null)
 			return;
 
Index: java/engine/org/apache/derby/impl/services/locks/LockTableVTI.java
===================================================================
--- java/engine/org/apache/derby/impl/services/locks/LockTableVTI.java	(revision 431605)
+++ java/engine/org/apache/derby/impl/services/locks/LockTableVTI.java	(working copy)
@@ -56,7 +56,12 @@
 	{
 		this.clonedLockTable = clonedLockTable;
 
-		outerControl = clonedLockTable.elements();
+		Hashtable ht = new Hashtable();
+		Hashtable[] tables = clonedLockTable.getTables();
+		for (int i = 0; i < tables.length; i++) {
+			ht.putAll(tables[i]);
+		}
+		outerControl = ht.elements();
 	}
 
 
