From 85ccf57a9ca45c3f53cf7e5a31734da160573f63 Mon Sep 17 00:00:00 2001 From: Yegor Bugayenko Date: Thu, 3 Nov 2022 12:38:44 +0300 Subject: [PATCH] #185 extra synchronization --- src/main/java/com/jcabi/xml/XSLDocument.java | 24 +++++++++++-------- .../java/com/jcabi/xml/XSLDocumentTest.java | 3 ++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/jcabi/xml/XSLDocument.java b/src/main/java/com/jcabi/xml/XSLDocument.java index d7855be..14eec80 100644 --- a/src/main/java/com/jcabi/xml/XSLDocument.java +++ b/src/main/java/com/jcabi/xml/XSLDocument.java @@ -357,7 +357,9 @@ public String toString() { public XML transform(final XML xml) { final DocumentBuilder builder; try { - builder = XSLDocument.DFACTORY.newDocumentBuilder(); + synchronized (XSLDocument.DFACTORY) { + builder = XSLDocument.DFACTORY.newDocumentBuilder(); + } } catch (final ParserConfigurationException ex) { throw new IllegalArgumentException( String.format( @@ -397,7 +399,7 @@ public String applyTo(final XML xml) { * @param xml XML * @param result Result * @since 0.11 - * @link https://stackoverflow.com/questions/4695489/capture-xslmessage-output-in-java + * @link Relevant SO question */ private void transformInto(final XML xml, final Result result) { final Transformer trans = this.transformer(); @@ -405,7 +407,9 @@ private void transformInto(final XML xml, final Result result) { trans.setErrorListener(errors); final long start = System.nanoTime(); try { - trans.transform(new DOMSource(xml.node()), result); + synchronized (XSLDocument.DFACTORY) { + trans.transform(new DOMSource(xml.node()), result); + } } catch (final TransformerException ex) { throw new IllegalArgumentException( String.format( @@ -431,10 +435,10 @@ private void transformInto(final XML xml, final Result result) { * @return The transformer */ private Transformer transformer() { - if (this.cached.get() == null) { - final Transformer trans; - synchronized (XSLDocument.TFACTORY) { + synchronized (XSLDocument.TFACTORY) { + if (this.cached.get() == null) { XSLDocument.TFACTORY.setURIResolver(this.sources); + final Transformer trans; try { trans = XSLDocument.TFACTORY.newTransformer( new StreamSource(new StringReader(this.xsl), this.sid) @@ -448,11 +452,11 @@ private Transformer transformer() { ex ); } + for (final Map.Entry ent : this.params.entrySet()) { + trans.setParameter(ent.getKey(), ent.getValue()); + } + this.cached.set(XSLDocument.forSaxon(trans)); } - for (final Map.Entry ent : this.params.entrySet()) { - trans.setParameter(ent.getKey(), ent.getValue()); - } - this.cached.set(XSLDocument.forSaxon(trans)); } return this.cached.get(); } diff --git a/src/test/java/com/jcabi/xml/XSLDocumentTest.java b/src/test/java/com/jcabi/xml/XSLDocumentTest.java index 1154ab0..b406a13 100644 --- a/src/test/java/com/jcabi/xml/XSLDocumentTest.java +++ b/src/test/java/com/jcabi/xml/XSLDocumentTest.java @@ -230,13 +230,14 @@ void transformsInManyThreads() throws Exception { ); final AtomicInteger done = new AtomicInteger(0); final CountDownLatch latch = new CountDownLatch(1); - final int total = 10; + final int total = 50; final ExecutorService exec = Executors.newFixedThreadPool(total); for (int task = 0; task < total; ++task) { exec.submit( () -> { latch.await(); xsl.transform(xml); + xsl.transform(xml); done.incrementAndGet(); return 0; }