List of usage examples for java.util.concurrent ArrayBlockingQueue add
public boolean add(E e)
From source file:Main.java
public static void main(String[] argv) throws Exception { int capacity = 10; ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(capacity); for (int i = 0; i < 10; i++) { queue.add(i); }/* ww w. jav a 2s . c o m*/ System.out.println(queue.remove(0)); System.out.println(queue); }
From source file:Main.java
public static void main(String[] argv) throws Exception { int capacity = 100; ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(capacity); for (int i = 0; i < 100; i++) { queue.add(i); }/*from w w w . j a va2 s . c o m*/ System.out.println(queue.contains(5)); queue.clear(); System.out.println(queue.contains(5)); }
From source file:Main.java
public static void main(String[] argv) throws Exception { int capacity = 10; ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(capacity); for (int i = 0; i < 10; i++) { queue.add(i); }//from www . java 2s . c o m Iterator<Integer> it = queue.iterator(); while (it.hasNext()) { System.out.println(it.next()); } }
From source file:org.kchine.rpf.db.MainNodeManager.java
private static void createTask() { try {/*from w w w .j av a 2 s .c o m*/ System.out.println(" create worker round at " + new Date()); long T1 = System.currentTimeMillis(); final ArrayBlockingQueue<String> indexesQueue = new ArrayBlockingQueue<String>(200); Vector<NodeDataDB> nodes = _registry.getNodeData(""); for (int i = 0; i < nodes.size(); ++i) { final String nodeName = nodes.elementAt(i).getNodeName(); String nodeIp = nodes.elementAt(i).getHostIp(); String nodePrefix = nodes.elementAt(i).getPoolPrefix(); Vector<HashMap<String, Object>> servants = _registry.getTableData("SERVANTS", "NODE_NAME='" + nodeName + "'" + " OR (HOST_IP='" + nodeIp + "' AND NAME like '" + nodePrefix + "%')"); final int missing = nodes.elementAt(i).getServantNbrMin() - servants.size(); if (missing > 0) { System.out.println("Node<" + nodeName + "> missing :" + missing); for (int j = 0; j < missing; ++j) { indexesQueue.add(nodeName); } } } Thread[] t = new Thread[10]; for (int i = 0; i < t.length; ++i) { t[i] = new Thread(new Runnable() { public void run() { while (true) { if (indexesQueue.isEmpty()) break; try { if (_nodeData == null) { if (!indexesQueue.isEmpty()) { String nodeName = indexesQueue.poll(); if (nodeName != null) { try { _registry.lookup( System.getProperty("node.manager.name") + '_' + nodeName); } catch (NotBoundException nbe) { NodeManager _manager = (NodeManager) _registry .lookup(System.getProperty("node.manager.name")); ManagedServant ms = _manager.createServant(nodeName); System.out.println(ms + " successfully created"); } } } } else { if (!indexesQueue.isEmpty()) { String nodeName = indexesQueue.poll(); if (nodeName != null && nodeName.equals(_nodeData.getNodeName())) { NodeManager _manager = (NodeManager) _registry.lookup(_nodeManagerName); ManagedServant ms = _manager.createServant(nodeName); System.out.println(ms + " successfully created"); } } } } catch (Exception e) { e.printStackTrace(); } finally { try { Thread.sleep(500); } catch (Exception e) { } } } } }); t[i].start(); } for (int i = 0; i < t.length; ++i) { t[i].join(); } System.out .println("Last create servants round took :" + (System.currentTimeMillis() - T1) + " millisec"); } catch (Exception e) { e.printStackTrace(); } }
From source file:org.datacleaner.api.AnalyzerResultFutureTest.java
public void testMultiThreadedListenerScenario() throws Exception { final int threadCount = 10; final Thread[] threads = new Thread[threadCount]; @SuppressWarnings({ "unchecked" }) final Listener<NumberResult>[] listeners = new Listener[threadCount]; final ArrayBlockingQueue<Object> resultQueue = new ArrayBlockingQueue<>(threadCount); for (int i = 0; i < listeners.length; i++) { listeners[i] = new Listener<NumberResult>() { @Override//from w w w .j av a 2s.c o m public void onSuccess(NumberResult result) { resultQueue.add(result); } @Override public void onError(RuntimeException error) { resultQueue.add(error); } }; } final Ref<NumberResult> resultRef = new LazyRef<NumberResult>() { @Override protected NumberResult fetch() throws Throwable { final long randomSleepTime = (long) (1000 * Math.random()); Thread.sleep(randomSleepTime); return new NumberResult(43); } }; final AnalyzerResultFuture<NumberResult> future = new AnalyzerResultFutureImpl<>("foo", resultRef); for (int i = 0; i < threads.length; i++) { final Listener<NumberResult> listener = listeners[i]; threads[i] = new Thread() { @Override public void run() { future.addListener(listener); } }; } final int halfOfTheThreads = threads.length / 2; for (int i = 0; i < halfOfTheThreads; i++) { threads[i].start(); } for (int i = 0; i < halfOfTheThreads; i++) { threads[i].join(); } future.get(); // to avoid any race conditions we use the drainTo method before calling // toString(). final List<Object> result = new ArrayList<>(); resultQueue.drainTo(result); assertEquals("[43, 43, 43, 43, 43]", result.toString()); assertEquals(halfOfTheThreads, result.size()); for (int i = halfOfTheThreads; i < threads.length; i++) { threads[i].start(); } for (int i = halfOfTheThreads; i < threads.length; i++) { threads[i].join(); } resultQueue.drainTo(result); assertEquals("[43, 43, 43, 43, 43, 43, 43, 43, 43, 43]", result.toString()); assertEquals(threads.length, result.size()); }
From source file:com.twofortyfouram.locale.sdk.host.test.Junit4SupportLoaderTestCase.java
/** * Runs a Loader synchronously and returns the result of the load. The loader will * be started, stopped, and destroyed by this method so it cannot be reused. * * @param loader The loader to run synchronously * @return The result from the loader//ww w . ja va 2s .com */ public <T> T getLoaderResultSynchronously(final Loader<T> loader) { // The test thread blocks on this queue until the loader puts it's result in final ArrayBlockingQueue<T> queue = new ArrayBlockingQueue<T>(1); // This callback runs on the "main" thread and unblocks the test thread // when it puts the result into the blocking queue final Loader.OnLoadCompleteListener<T> listener = new Loader.OnLoadCompleteListener<T>() { @Override public void onLoadComplete(Loader<T> completedLoader, T data) { // Shut the loader down completedLoader.unregisterListener(this); completedLoader.stopLoading(); completedLoader.reset(); // Store the result, unblocking the test thread queue.add(data); } }; // This handler runs on the "main" thread of the process since AsyncTask // is documented as needing to run on the main thread and many Loaders use // AsyncTask final Handler mainThreadHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { loader.registerListener(0, listener); loader.startLoading(); } }; // Ask the main thread to start the loading process mainThreadHandler.sendEmptyMessage(0); // Block on the queue waiting for the result of the load to be inserted T result; while (true) { try { result = queue.take(); break; } catch (InterruptedException e) { throw new RuntimeException("waiting thread interrupted", e); } } return result; }
From source file:org.mozilla.gecko.background.fxa.TestAccountLoader.java
/** * Runs a Loader synchronously and returns the result of the load. The loader will * be started, stopped, and destroyed by this method so it cannot be reused. * * @param loader The loader to run synchronously * @return The result from the loader//w ww . j av a 2 s . c om */ public <T> T getLoaderResultSynchronously(final Loader<T> loader) { // The test thread blocks on this queue until the loader puts it's result in final ArrayBlockingQueue<AtomicReference<T>> queue = new ArrayBlockingQueue<AtomicReference<T>>(1); // This callback runs on the "main" thread and unblocks the test thread // when it puts the result into the blocking queue final OnLoadCompleteListener<T> listener = new OnLoadCompleteListener<T>() { @Override public void onLoadComplete(Loader<T> completedLoader, T data) { // Shut the loader down completedLoader.unregisterListener(this); completedLoader.stopLoading(); completedLoader.reset(); // Store the result, unblocking the test thread queue.add(new AtomicReference<T>(data)); } }; // This handler runs on the "main" thread of the process since AsyncTask // is documented as needing to run on the main thread and many Loaders use // AsyncTask final Handler mainThreadHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { loader.registerListener(0, listener); loader.startLoading(); } }; // Ask the main thread to start the loading process mainThreadHandler.sendEmptyMessage(0); // Block on the queue waiting for the result of the load to be inserted T result; while (true) { try { result = queue.take().get(); break; } catch (InterruptedException e) { throw new RuntimeException("waiting thread interrupted", e); } } return result; }
From source file:com.scvngr.levelup.core.test.SupportLoaderTestCase.java
/** * Runs a Loader synchronously and returns the result of the load. The loader will be started, * stopped, and destroyed by this method so it cannot be reused. * * @param loader The loader to run synchronously * @return The result from the loader// w w w .j a v a 2s. c o m */ public <T> T getLoaderResultSynchronously(final Loader<T> loader) { // The test thread blocks on this queue until the loader puts its result in final ArrayBlockingQueue<T> queue = new ArrayBlockingQueue<T>(1); final CountDownLatch latch = new CountDownLatch(1); // This callback runs on the "main" thread and unblocks the test thread // when it puts the result into the blocking queue final OnLoadCompleteListener<T> listener = new OnLoadCompleteListener<T>() { @Override public void onLoadComplete(final Loader<T> completedLoader, final T data) { // Shut the loader down completedLoader.unregisterListener(this); completedLoader.stopLoading(); completedLoader.reset(); // Store the result, unblocking the test thread if (null != data) { queue.add(data); } latch.countDown(); } }; // This handler runs on the "main" thread of the process since AsyncTask // is documented as needing to run on the main thread and many Loaders use // AsyncTask final Handler mainThreadHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(final Message msg) { loader.registerListener(0, listener); loader.startLoading(); } }; // Ask the main thread to start the loading process mainThreadHandler.sendEmptyMessage(0); // Block on the queue waiting for the result of the load to be inserted T result; while (true) { try { latch.await(); result = queue.peek(); break; } catch (final InterruptedException e) { throw new RuntimeException("waiting thread interrupted", e); } } return result; }
From source file:org.kchine.r.server.RListener.java
public static String[] clusterApply(final String cl, final String varName, final String functionName, final String ato, final String asynch) { new Thread(new Runnable() { public void run() { try { Cluster cluster = _clustersHash.get(cl); if (cluster == null) { new Thread(new Runnable() { public void run() { try { DirectJNI.getInstance().getRServices() .consoleSubmit(convertToPrintCommand("Invalid cluster")); } catch (Exception e) { e.printStackTrace(); }// www . j a v a 2 s.c om } }).start(); } RObject v = DirectJNI.getInstance().getRServices().getObject(varName); RObject vtemp = null; if (v.getClass() == RMatrix.class) { vtemp = ((RMatrix) v).getValue(); } else if (v.getClass() == RArray.class) { vtemp = ((RArray) v).getValue(); } else { vtemp = v; } final RObject var = vtemp; final VWrapper vwrapper = new VWrapper() { public int getSize() { if (var.getClass() == RNumeric.class) { return ((RNumeric) var).getValue().length; } else if (var.getClass() == RInteger.class) { return ((RInteger) var).getValue().length; } else if (var.getClass() == RChar.class) { return ((RChar) var).getValue().length; } else if (var.getClass() == RLogical.class) { return ((RLogical) var).getValue().length; } else if (var.getClass() == RComplex.class) { return ((RComplex) var).getReal().length; } else if (var.getClass() == RList.class) { return ((RList) var).getValue().length; } return 0; } public RObject getElementAt(int i) { if (var.getClass() == RNumeric.class) { return new RNumeric(((RNumeric) var).getValue()[i]); } else if (var.getClass() == RInteger.class) { return new RInteger(((RInteger) var).getValue()[i]); } else if (var.getClass() == RChar.class) { return new RChar(((RChar) var).getValue()[i]); } else if (var.getClass() == RLogical.class) { return new RLogical(((RLogical) var).getValue()[i]); } else if (var.getClass() == RComplex.class) { return new RComplex(new double[] { ((RComplex) var).getReal()[i] }, new double[] { ((RComplex) var).getImaginary()[i] }, ((RComplex) var).getIndexNA() != null ? new int[] { ((RComplex) var).getIndexNA()[i] } : null, ((RComplex) var).getNames() != null ? new String[] { ((RComplex) var).getNames()[i] } : null); } else if (var.getClass() == RList.class) { return (RObject) ((RList) var).getValue()[i]; } return null; } public Object gatherResults(RObject[] f) { if (var.getClass() == RList.class) { return f; } else { Class<?> resultClass = f[0].getClass(); RObject result = null; if (resultClass == RNumeric.class) { double[] t = new double[f.length]; for (int i = 0; i < f.length; ++i) t[i] = ((RNumeric) f[i]).getValue()[0]; result = new RNumeric(t); } else if (resultClass == RInteger.class) { int[] t = new int[f.length]; for (int i = 0; i < f.length; ++i) t[i] = ((RInteger) f[i]).getValue()[0]; result = new RInteger(t); } else if (resultClass == RChar.class) { String[] t = new String[f.length]; for (int i = 0; i < f.length; ++i) t[i] = ((RChar) f[i]).getValue()[0]; result = new RChar(t); } else if (resultClass == RLogical.class) { boolean[] t = new boolean[f.length]; for (int i = 0; i < f.length; ++i) t[i] = ((RLogical) f[i]).getValue()[0]; result = new RLogical(t); } else if (resultClass == RComplex.class) { double[] real = new double[f.length]; double[] im = new double[f.length]; for (int i = 0; i < f.length; ++i) { real[i] = ((RComplex) f[i]).getReal()[0]; im[i] = ((RComplex) f[i]).getImaginary()[0]; } result = new RComplex(real, im, null, null); } else { throw new RuntimeException( "Can't Handle this result type :" + resultClass.getName()); } return result; } } }; if (vwrapper.getSize() == 0) { new Thread(new Runnable() { public void run() { try { DirectJNI.getInstance().getRServices() .consoleSubmit(convertToPrintCommand("0 elements in data")); } catch (Exception e) { e.printStackTrace(); } } }).start(); } Vector<RServices> workers = cluster.getWorkers(); final ArrayBlockingQueue<Integer> indexesQueue = new ArrayBlockingQueue<Integer>( vwrapper.getSize()); for (int i = 0; i < vwrapper.getSize(); ++i) indexesQueue.add(i); final ArrayBlockingQueue<RServices> workersQueue = new ArrayBlockingQueue<RServices>( workers.size()); for (int i = 0; i < workers.size(); ++i) workersQueue.add(workers.elementAt(i)); final RObject[] result = new RObject[vwrapper.getSize()]; for (int i = 0; i < workers.size(); ++i) { new Thread(new Runnable() { public void run() { RServices r = workersQueue.poll(); while (indexesQueue.size() > 0) { Integer idx = indexesQueue.poll(); if (idx != null) { try { result[idx] = r.call(functionName, vwrapper.getElementAt(idx)); } catch (Exception e) { e.printStackTrace(); result[idx] = nullObject; } } } } }).start(); } while (true) { int count = 0; for (int i = 0; i < result.length; ++i) if (result[i] != null) ++count; if (count == result.length) break; Thread.sleep(100); } Object reconstituedObject = vwrapper.gatherResults(result); if (v.getClass() == RMatrix.class) { ((RArray) v).setValue((RVector) reconstituedObject); } else if (v.getClass() == RArray.class) { ((RArray) v).setValue((RVector) reconstituedObject); } else if (v.getClass() == RList.class) { ((RList) v).setValue((RObject[]) reconstituedObject); } else { v = (RObject) reconstituedObject; } final RObject final_v = v; new Thread(new Runnable() { public void run() { try { DirectJNI.getInstance().getRServices().putAndAssign(final_v, (ato.equals("") ? functionName + "_" + varName : ato)); DirectJNI.getInstance().getRServices().consoleSubmit( convertToPrintCommand("Cluster Apply result assigned to R variable " + (ato.equals("") ? functionName + "_" + varName : ato) + "\n")); } catch (Exception e) { e.printStackTrace(); } } }).start(); } catch (Exception e) { e.printStackTrace(); } } }).start(); return new String[] { "OK", convertToPrintCommand("Cluster Apply Submitted in background..") }; }
From source file:it.unimi.di.big.mg4j.document.WikipediaDocumentSequence.java
@Override public DocumentIterator iterator() throws IOException { final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); saxParserFactory.setNamespaceAware(true); final MutableString nameSpaceAccumulator = new MutableString(); final ObjectOpenHashSet<MutableString> nameSpacesAccumulator = new ObjectOpenHashSet<MutableString>(); final ArrayBlockingQueue<DocumentFactory> freeFactories = new ArrayBlockingQueue<DocumentFactory>(16); for (int i = freeFactories.remainingCapacity(); i-- != 0;) freeFactories.add(this.factory.copy()); final ArrayBlockingQueue<DocumentAndFactory> readyDocumentsAndFactories = new ArrayBlockingQueue<DocumentAndFactory>( freeFactories.size());//from ww w . j ava2 s . c om final SAXParser parser; try { parser = saxParserFactory.newSAXParser(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } final DefaultHandler handler = new DefaultHandler() { private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); private boolean inText; private boolean inTitle; private boolean inId; private boolean inTimestamp; private boolean inNamespaceDef; private boolean redirect; private MutableString text = new MutableString(); private MutableString title = new MutableString(); private MutableString id = new MutableString(); private MutableString timestamp = new MutableString(); private final Reference2ObjectMap<Enum<?>, Object> metadata = new Reference2ObjectOpenHashMap<Enum<?>, Object>(); { metadata.put(PropertyBasedDocumentFactory.MetadataKeys.ENCODING, "UTF-8"); metadata.put(MetadataKeys.REDIRECT, redirectAnchors); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if ("page".equals(localName)) { redirect = inText = inTitle = inId = inTimestamp = false; text.length(0); title.length(0); id.length(0); timestamp.length(0); } else if ("text".equals(localName)) inText = true; else if ("title".equals(localName) && title.length() == 0) inTitle = true; // We catch only the first id/title elements. else if ("id".equals(localName) && id.length() == 0) inId = true; else if ("timestamp".equals(localName) && timestamp.length() == 0) inTimestamp = true; else if ("redirect".equals(localName)) { redirect = true; if (attributes.getValue("title") != null) // Accumulate the title of the page as virtual text of the redirect page. synchronized (redirectAnchors) { final String link = Encoder.encodeTitleToUrl(attributes.getValue("title"), true); redirectAnchors.add( new AnchorExtractor.Anchor(new MutableString(baseURL.length() + link.length()) .append(baseURL).append(link), title.copy())); } } else if ("namespace".equals(localName)) { // Found a new namespace inNamespaceDef = true; nameSpaceAccumulator.length(0); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("namespace".equals(localName)) { // Collecting a namespace if (nameSpaceAccumulator.length() != 0) nameSpacesAccumulator.add(nameSpaceAccumulator.copy().toLowerCase()); return; } if ("namespaces".equals(localName)) { // All namespaces collected nameSpaces = ImmutableSet.copyOf(nameSpacesAccumulator); return; } if (!redirect) { if ("title".equals(localName)) { // Set basic metadata for the page metadata.put(PropertyBasedDocumentFactory.MetadataKeys.TITLE, title.copy()); String link = Encoder.encodeTitleToUrl(title.toString(), true); metadata.put(PropertyBasedDocumentFactory.MetadataKeys.URI, new MutableString(baseURL.length() + link.length()).append(baseURL).append(link)); inTitle = false; } else if ("id".equals(localName)) { metadata.put(MetadataKeys.ID, Long.valueOf(id.toString())); inId = false; } else if ("timestamp".equals(localName)) { try { metadata.put(MetadataKeys.LASTEDIT, dateFormat.parse(timestamp.toString())); } catch (ParseException e) { throw new RuntimeException(e.getMessage(), e); } inTimestamp = false; } else if ("text".equals(localName)) { inText = false; if (!keepNamespaced) { // Namespaces are case-insensitive and language-dependent final int pos = title.indexOf(':'); if (pos != -1 && nameSpaces.contains(title.substring(0, pos).toLowerCase())) return; } try { final MutableString html = new MutableString(); DocumentFactory freeFactory; try { freeFactory = freeFactories.take(); } catch (InterruptedException e) { throw new RuntimeException(e.getMessage(), e); } if (parseText) { if (DISAMBIGUATION.search(text) != -1) { // It's a disambiguation page. /* Roi's hack: duplicate links using the page title, so the generic name will end up as anchor text. */ final MutableString newLinks = new MutableString(); for (int start = 0, end; (start = BRACKETS_OPEN.search(text, start)) != -1; start = end) { end = start; final int endOfLink = text.indexOfAnyOf(END_OF_DISAMBIGUATION_LINK, start); // Note that we don't escape title because we are working at the Wikipedia raw text level. if (endOfLink != -1) { newLinks.append(text.array(), start, endOfLink - start).append('|') .append(title).append("]]\n"); end = endOfLink; } end++; } text.append(newLinks); } // We separate categories by OXOXO, so we don't get overflowing phrases. final MutableString category = new MutableString(); for (int start = 0, end; (start = CATEGORY_START.search(text, start)) != -1; start = end) { end = BRACKETS_CLOSED.search(text, start += CATEGORY_START.length()); if (end != -1) category.append(text.subSequence(start, end)).append(" OXOXO "); else break; } metadata.put(MetadataKeys.CATEGORY, category); // Heuristics to get the first paragraph metadata.put(MetadataKeys.FIRSTPAR, new MutableString()); String plainText = wikiModel.render(new PlainTextConverter(true), text.toString()); for (int start = 0; start < plainText.length(); start++) { //System.err.println("Examining " + plainText.charAt( start ) ); if (Character.isWhitespace(plainText.charAt(start))) continue; if (plainText.charAt(start) == '{') { //System.err.print( "Braces " + start + " text: \"" + plainText.subSequence( start, start + 10 ) + "\" -> " ); start = BRACES_CLOSED.search(plainText, start); //System.err.println( start + " text: \"" + plainText.subSequence( start, start + 10 ) + "\"" ); if (start == -1) break; start++; } else if (plainText.charAt(start) == '[') { start = BRACKETS_CLOSED.search(plainText, start); if (start == -1) break; start++; } else { final int end = plainText.indexOf('\n', start); if (end != -1) metadata.put(MetadataKeys.FIRSTPAR, new MutableString(plainText.substring(start, end))); break; } } try { wikiModel.render(new HTMLConverter(), text.toString(), html, false, true); final Map<String, String> categories = wikiModel.getCategories(); // Put back category links in the page (they have been parsed by bliki and to not appear anymore in the HTML rendering) for (Entry<String, String> entry : categories.entrySet()) { final String key = entry.getKey(); final String value = entry.getValue().trim(); if (value.length() != 0) // There are empty such things html.append("\n<a href=\"").append(baseURL).append("Category:") .append(Encoder.encodeTitleToUrl(key, true)).append("\">") .append(HtmlEscapers.htmlEscaper().escape(key)) .append("</a>\n"); } } catch (Exception e) { LOGGER.error("Unexpected exception while parsing " + title, e); } } readyDocumentsAndFactories.put(new DocumentAndFactory( freeFactory.getDocument(IOUtils.toInputStream(html, Charsets.UTF_8), new Reference2ObjectOpenHashMap<Enum<?>, Object>(metadata)), freeFactory)); } catch (InterruptedException e) { throw new RuntimeException(e.getMessage(), e); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (inText && parseText) text.append(ch, start, length); if (inTitle) title.append(ch, start, length); if (inId) id.append(ch, start, length); if (inTimestamp) timestamp.append(ch, start, length); if (inNamespaceDef) { nameSpaceAccumulator.append(ch, start, length); inNamespaceDef = false; // Dirty, but it works } } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { if (inText && parseText) text.append(ch, start, length); if (inTitle) title.append(ch, start, length); } }; final Thread parsingThread = new Thread() { public void run() { try { InputStream in = new FileInputStream(wikipediaXmlDump); if (bzipped) in = new BZip2CompressorInputStream(in); parser.parse( new InputSource(new InputStreamReader(new FastBufferedInputStream(in), Charsets.UTF_8)), handler); readyDocumentsAndFactories.put(END); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } }; parsingThread.start(); return new AbstractDocumentIterator() { private DocumentFactory lastFactory; @Override public Document nextDocument() throws IOException { try { final DocumentAndFactory documentAndFactory = readyDocumentsAndFactories.take(); if (lastFactory != null) freeFactories.put(lastFactory); if (documentAndFactory == END) return null; lastFactory = documentAndFactory.factory; return documentAndFactory.document; } catch (InterruptedException e) { throw new RuntimeException(e.getMessage(), e); } } }; }