@Test
	public void testMultiThreads() {
		int pageSize = 1024 * 1024 * 32;
		mappedPageFactory = new MappedPageFactoryImpl(pageSize, testDir + "/test_multi_threads");
		
		int threadNum = 100;
		int pageNumLimit = 50;
		
		Set<IMappedPage> pageSet = Collections.newSetFromMap(new ConcurrentHashMap<IMappedPage, Boolean>());
		List<ByteBuffer> localBufferList = Collections.synchronizedList(new ArrayList<ByteBuffer>());
		
		Worker[] workers = new Worker[threadNum];
		for(int i = 0; i < threadNum; i++) {
			workers[i] = new Worker(i, mappedPageFactory, pageNumLimit, pageSet, localBufferList);
		}
		for(int i = 0; i < threadNum; i++) {
			workers[i].start();
		}
		
		for(int i = 0; i< threadNum; i++) {
			try {
				workers[i].join();
			} catch (InterruptedException e) {
				// ignore
			}
		}
		
		assertTrue(localBufferList.size() == threadNum * pageNumLimit);
		assertTrue(pageSet.size() == pageNumLimit);
		
		// verify thread locality
		for(int i = 0; i < localBufferList.size(); i++) {
			for(int j = i + 1; j < localBufferList.size(); j++) {
				if (localBufferList.get(i) == localBufferList.get(j)) {
					fail("thread local buffer is not thread local");
				}
			}
		}
	}