Index: lucene/core/src/test/org/apache/lucene/store/TestDirectory.java
===================================================================
--- lucene/core/src/test/org/apache/lucene/store/TestDirectory.java	(revision 1363907)
+++ lucene/core/src/test/org/apache/lucene/store/TestDirectory.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.Arrays;
 
@@ -41,8 +42,105 @@
       }
     }
   }
+  
+  public void testThreadSafety() throws Exception {
+    File tmpdir = _TestUtil.getTempDir("threadSafety");
+    tmpdir.mkdirs();
+    Directory fsdir = random().nextBoolean() ? new MMapDirectory(tmpdir) : new NIOFSDirectory(tmpdir);
+    final Directory dir = new NRTCachingDirectory(fsdir, 0.5, 1);//newDirectory();
+    
+    class TheThread extends Thread {
+      private String name;
 
+      public TheThread(String name) {
+        this.name = name;
+      }
+      
+      public void run() {
+        for (int i = 0; i < 3000; i++) {
+          String fileName = this.name + i;
+          try {
+            //System.out.println("create:" + fileName);
+            IndexOutput output = dir.createOutput(fileName, newIOContext(random()));
+            output.close();
+            assertTrue(dir.fileExists(fileName));
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      }
+    };
+    
+    class TheThread2 extends Thread {
+      private String name;
 
+      public TheThread2(String name) {
+        this.name = name;
+      }
+      
+      public void run() {
+        for (int i = 0; i < 10000; i++) {
+          try {
+            String[] files = dir.listAll();
+            for (String file : files) {
+              //System.out.println("file:" + file);
+             try {
+              IndexInput input = dir.openInput(file, newIOContext(random()));
+              input.close();
+              } catch (FileNotFoundException e) {
+                
+              }
+              if (random().nextBoolean()) {
+                break;
+              }
+            }
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      }
+    };
+    
+    class TheThread3 extends Thread {
+      private String name;
+
+      public TheThread3(String name) {
+        this.name = name;
+      }
+      
+      public void run() {
+        for (int i = 0; i < 1000; i++) {
+          try {
+            String[] files = dir.listAll();
+            for (String file : files) {
+              dir.deleteFile(file);
+              assertFalse(dir.fileExists(file));
+            }
+            if (random().nextBoolean()) {
+              break;
+            }
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      }
+    };
+    
+    TheThread theThread = new TheThread("t1");
+    TheThread2 theThread2 = new TheThread2("t2");
+    TheThread3 theThread3 = new TheThread3("t3");
+    theThread.start();
+    theThread2.start();
+    //theThread3.start();
+    
+    theThread.join();
+    theThread2.join();
+    //theThread3.join();
+    
+    dir.close();
+  }
+
+
   // Test that different instances of FSDirectory can coexist on the same
   // path, can read, write, and lock files.
   public void testDirectInstantiation() throws Exception {
