From 2fbc50e76fda38adc88a1577886718a6e17a0acc Mon Sep 17 00:00:00 2001 From: Steve Hannah Date: Fri, 6 Feb 2015 16:47:59 -0800 Subject: [PATCH] Most of the elements are in place for monitors to work... something is wrong tough because I get errors when I try to compile files with synchronized sections. --- .../org/teavm/classlib/java/lang/TObject.java | 33 ++++++++++ .../org/teavm/classlib/java/lang/TThread.java | 6 +- .../src/main/java/org/teavm/cache/AstIO.java | 10 ++++ .../cache/DiskRegularMethodNodeCache.java | 10 ++++ .../javascript/BreakToContinueReplacer.java | 10 ++++ .../javascript/CertainBlockCountVisitor.java | 10 ++++ .../teavm/javascript/OptimizingVisitor.java | 10 ++++ .../javascript/RedundantLabelEliminator.java | 10 ++++ .../javascript/ReferenceCountingVisitor.java | 10 ++++ .../java/org/teavm/javascript/Renderer.java | 34 +++++++++++ .../teavm/javascript/StatementGenerator.java | 16 ++++- .../org/teavm/javascript/TryCatchFinder.java | 10 ++++ .../javascript/UnusedVariableEliminator.java | 10 ++++ .../javascript/ast/MonitorEnterStatement.java | 60 +++++++++++++++++++ .../javascript/ast/MonitorExitStatement.java | 60 +++++++++++++++++++ .../teavm/javascript/ast/RenamingVisitor.java | 10 ++++ .../javascript/ast/StatementVisitor.java | 4 ++ .../main/java/org/teavm/model/BasicBlock.java | 15 ++++- .../model/util/InstructionVariableMapper.java | 4 +- .../optimization/GlobalValueNumbering.java | 6 +- .../java/org/teavm/parsing/ProgramParser.java | 15 ++++- .../org/teavm/parsing/SSATransformer.java | 4 +- .../teavm-samples-async/nb-configuration.xml | 19 ++++++ .../teavm-samples-async/nbactions.xml | 17 ++++++ .../org/teavm/samples/async/AsyncProgram.java | 22 +++++++ 25 files changed, 402 insertions(+), 13 deletions(-) create mode 100644 teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java create mode 100644 teavm-core/src/main/java/org/teavm/javascript/ast/MonitorExitStatement.java create mode 100644 teavm-samples/teavm-samples-async/nb-configuration.xml create mode 100644 teavm-samples/teavm-samples-async/nbactions.xml diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java index 5de13b11f..a343528ed 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TObject.java @@ -29,6 +29,39 @@ import org.teavm.runtime.Async; */ @Superclass("") public class TObject { + + private TThread owner; + private TObject monitorLock; + private int monitorCount=0; + + static void monitorEnter(TObject o){ + if ( o.monitorLock == null ){ + o.monitorLock = new TObject(); + } + while (o.owner != null && o.owner != TThread.currentThread() ){ + try { + o.monitorLock.wait(); + } catch (InterruptedException ex) { + + } + } + o.owner = TThread.currentThread(); + o.monitorCount++; + + } + + static void monitorExit(TObject o){ + o.owner = null; + o.monitorCount--; + if ( o.monitorLock != null ){ + o.monitorLock.notifyAll(); + } + } + + static boolean holdsLock(TObject o){ + return o.owner == TThread.currentThread(); + } + @Rename("fakeInit") public TObject() { } diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index 77d8c6c1e..b03b29853 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -112,8 +112,8 @@ public class TThread extends TObject implements TRunnable { return id; } - public static boolean holdsLock(@SuppressWarnings("unused") TObject obj) { - return true; + public static boolean holdsLock(TObject obj) { + return TObject.holdsLock(obj); } public static void sleep(long millis) throws TInterruptedException { @@ -123,4 +123,6 @@ public class TThread extends TObject implements TRunnable { @Async @GeneratedBy(ThreadNativeGenerator.class) private static native void sleep(double millis) throws TInterruptedException; + + } diff --git a/teavm-core/src/main/java/org/teavm/cache/AstIO.java b/teavm-core/src/main/java/org/teavm/cache/AstIO.java index 3fda51324..6edeb906b 100644 --- a/teavm-core/src/main/java/org/teavm/cache/AstIO.java +++ b/teavm-core/src/main/java/org/teavm/cache/AstIO.java @@ -508,6 +508,16 @@ public class AstIO { throw new IOExceptionWrapper(e); } } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } private NodeLocation readLocation(DataInput input) throws IOException { diff --git a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java index 33253cd80..c597c6490 100644 --- a/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java +++ b/teavm-core/src/main/java/org/teavm/cache/DiskRegularMethodNodeCache.java @@ -261,6 +261,16 @@ public class DiskRegularMethodNodeCache implements RegularMethodNodeCache { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } static class Item { diff --git a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java index de500d61f..01e8d7a73 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/BreakToContinueReplacer.java @@ -116,4 +116,14 @@ class BreakToContinueReplacer implements StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java index bd475a54a..66152cb01 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/CertainBlockCountVisitor.java @@ -111,4 +111,14 @@ class CertainBlockCountVisitor implements StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java index 3d432424b..0d3474098 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/OptimizingVisitor.java @@ -618,4 +618,14 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor { public void visit(RestoreAsyncStatement statement) { resultStmt = statement; } + + @Override + public void visit(MonitorEnterStatement statement) { + resultStmt = statement; + } + + @Override + public void visit(MonitorExitStatement statement) { + resultStmt = statement; + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java index 30111b45d..bca649fd4 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/RedundantLabelEliminator.java @@ -121,4 +121,14 @@ class RedundantLabelEliminator implements StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java index 1e5f742af..218b8ea45 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ReferenceCountingVisitor.java @@ -115,4 +115,14 @@ class ReferenceCountingVisitor implements StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index d71d3455b..a74505f75 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -55,6 +55,40 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext private DeferredCallSite prevCallSite; private boolean async; + @Override + public void visit(MonitorEnterStatement statement) { + if (async){ + try { + MethodReference monitorEnterRef = new MethodReference( + Object.class, "monitorEnter", Object.class, void.class); + + writer.appendMethodBody(monitorEnterRef).append("("); + statement.acceptVisitor(this); + writer.append(");").softNewLine(); + + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); + } + } + } + + @Override + public void visit(MonitorExitStatement statement) { + if (async){ + try { + MethodReference monitorExitRef = new MethodReference( + Object.class, "monitorExit", Object.class, void.class); + + writer.appendMethodBody(monitorExitRef).append("("); + statement.acceptVisitor(this); + writer.append(");").softNewLine(); + } catch (IOException ex){ + throw new RenderingException("IO error occured", ex); + } + + } + } + private static class InjectorHolder { public final Injector injector; diff --git a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java index 3595f4611..432bb0d5a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/StatementGenerator.java @@ -670,10 +670,24 @@ class StatementGenerator implements InstructionVisitor { @Override public void visit(MonitorEnterInstruction insn) { + MonitorEnterStatement stmt = new MonitorEnterStatement(); + stmt.setLocation(currentLocation); + + VariableExpr expr = new VariableExpr(); + expr.setIndex(insn.getObjectRef().getIndex()); + expr.setLocation(currentLocation); + stmt.setObjectRef(expr); + statements.add(stmt); } @Override public void visit(MonitorExitInstruction insn) { - + MonitorExitStatement stmt = new MonitorExitStatement(); + stmt.setLocation(currentLocation); + VariableExpr expr = new VariableExpr(); + expr.setLocation(currentLocation); + expr.setIndex(insn.getObjectRef().getIndex()); + stmt.setObjectRef(expr); + statements.add(stmt); } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java index 7618fb355..4b54c49e2 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java +++ b/teavm-core/src/main/java/org/teavm/javascript/TryCatchFinder.java @@ -114,4 +114,14 @@ class TryCatchFinder implements StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java index 719a1a842..57845257a 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java +++ b/teavm-core/src/main/java/org/teavm/javascript/UnusedVariableEliminator.java @@ -228,4 +228,14 @@ class UnusedVariableEliminator implements ExprVisitor, StatementVisitor { @Override public void visit(RestoreAsyncStatement statement) { } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java new file mode 100644 index 000000000..1735e8d00 --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorEnterStatement.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.javascript.ast; + +/** + * + * @author shannah + */ +public class MonitorEnterStatement extends Statement { + + private NodeLocation location; + private VariableExpr objectRef; + + @Override + public void acceptVisitor(StatementVisitor visitor) { + visitor.visit(this); + } + + /** + * @return the location + */ + public NodeLocation getLocation() { + return location; + } + + /** + * @param location the location to set + */ + public void setLocation(NodeLocation location) { + this.location = location; + } + + /** + * @return the objectRef + */ + public VariableExpr getObjectRef() { + return objectRef; + } + + /** + * @param objectRef the objectRef to set + */ + public void setObjectRef(VariableExpr objectRef) { + this.objectRef = objectRef; + } + +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorExitStatement.java b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorExitStatement.java new file mode 100644 index 000000000..b13fd370a --- /dev/null +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/MonitorExitStatement.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.javascript.ast; + +/** + * + * @author shannah + */ +public class MonitorExitStatement extends Statement { + + private NodeLocation location; + private VariableExpr objectRef; + + @Override + public void acceptVisitor(StatementVisitor visitor) { + visitor.visit(this); + } + + /** + * @return the location + */ + public NodeLocation getLocation() { + return location; + } + + /** + * @param location the location to set + */ + public void setLocation(NodeLocation location) { + this.location = location; + } + + /** + * @return the objectRef + */ + public VariableExpr getObjectRef() { + return objectRef; + } + + /** + * @param objectRef the objectRef to set + */ + public void setObjectRef(VariableExpr objectRef) { + this.objectRef = objectRef; + } + +} diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java index cb3b363ec..402fe6d3c 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/RenamingVisitor.java @@ -198,4 +198,14 @@ public class RenamingVisitor implements StatementVisitor, ExprVisitor { statement.setReceiver(varNames[statement.getReceiver()]); } } + + @Override + public void visit(MonitorEnterStatement statement) { + + } + + @Override + public void visit(MonitorExitStatement statement) { + + } } diff --git a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java index 8d984747f..86cbb8474 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java +++ b/teavm-core/src/main/java/org/teavm/javascript/ast/StatementVisitor.java @@ -45,4 +45,8 @@ public interface StatementVisitor { void visit(TryCatchStatement statement); void visit(RestoreAsyncStatement statement); + + void visit(MonitorEnterStatement statement); + + void visit(MonitorExitStatement statement); } diff --git a/teavm-core/src/main/java/org/teavm/model/BasicBlock.java b/teavm-core/src/main/java/org/teavm/model/BasicBlock.java index 737f7963c..81c911488 100644 --- a/teavm-core/src/main/java/org/teavm/model/BasicBlock.java +++ b/teavm-core/src/main/java/org/teavm/model/BasicBlock.java @@ -16,6 +16,7 @@ package org.teavm.model; import java.util.*; +import org.teavm.model.instructions.AssignInstruction; import org.teavm.model.instructions.InstructionReader; /** @@ -66,7 +67,19 @@ public class BasicBlock implements BasicBlockReader { @Override public void add(int index, Instruction e) { if (e.getBasicBlock() != null) { - throw new IllegalArgumentException("This instruction is in some basic block"); + if (e instanceof AssignInstruction){ + AssignInstruction ae = (AssignInstruction)e; + System.out.println("Assignment "+ae.getReceiver()+" -> "+ae.getAssignee()); + System.out.println(ae.getReceiver().getDebugNames()); + System.out.println(ae.getReceiver().getIndex()); + System.out.println(ae.getReceiver().getProgram()); + System.out.println(ae.getAssignee().getDebugNames()); + System.out.println(ae.getAssignee().getIndex()); + System.out.println(ae.getAssignee().getProgram()); + + System.out.println(ae.getBasicBlock().getInstructions()); + } + throw new IllegalArgumentException("This instruction is in some basic block "+e+", "+e.getLocation()); } e.setBasicBlock(BasicBlock.this); instructions.add(index, e); diff --git a/teavm-core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java b/teavm-core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java index 97d0e658c..65da6ac85 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InstructionVariableMapper.java @@ -231,12 +231,12 @@ public abstract class InstructionVariableMapper implements InstructionVisitor { @Override public void visit(MonitorEnterInstruction insn) { - + insn.setObjectRef(map(insn.getObjectRef())); } @Override public void visit(MonitorExitInstruction insn) { - + insn.setObjectRef(map(insn.getObjectRef())); } diff --git a/teavm-core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java b/teavm-core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java index a6d4ac1ca..51cdfd741 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java +++ b/teavm-core/src/main/java/org/teavm/optimization/GlobalValueNumbering.java @@ -421,12 +421,14 @@ public class GlobalValueNumbering implements MethodOptimization { @Override public void visit(MonitorEnterInstruction insn) { - + int val = map[insn.getObjectRef().getIndex()]; + insn.setObjectRef(program.variableAt(val)); } @Override public void visit(MonitorExitInstruction insn) { - + int val = map[insn.getObjectRef().getIndex()]; + insn.setObjectRef(program.variableAt(val)); } }; } diff --git a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java index f3ab0237b..8a9f92ea4 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -1556,10 +1556,19 @@ public class ProgramParser implements VariableDebugInformation { nextIndexes = new int[0]; return; } - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - popSingle(); + case Opcodes.MONITORENTER: { + MonitorEnterInstruction insn = new MonitorEnterInstruction(); + insn.setObjectRef(getVariable(popSingle())); + addInstruction(insn); break; + } + case Opcodes.MONITOREXIT: { + MonitorExitInstruction insn = new MonitorExitInstruction(); + insn.setObjectRef(getVariable(popSingle())); + addInstruction(insn); + break; + } + } } diff --git a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java index b16afe881..a48a82dda 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java +++ b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java @@ -450,12 +450,12 @@ public class SSATransformer { @Override public void visit(MonitorEnterInstruction insn) { - + insn.setObjectRef(use(insn.getObjectRef())); } @Override public void visit(MonitorExitInstruction insn) { - + insn.setObjectRef(use(insn.getObjectRef())); } }; } diff --git a/teavm-samples/teavm-samples-async/nb-configuration.xml b/teavm-samples/teavm-samples-async/nb-configuration.xml new file mode 100644 index 000000000..792bc673f --- /dev/null +++ b/teavm-samples/teavm-samples-async/nb-configuration.xml @@ -0,0 +1,19 @@ + + + + + + maven + gfv3ee6 + + diff --git a/teavm-samples/teavm-samples-async/nbactions.xml b/teavm-samples/teavm-samples-async/nbactions.xml new file mode 100644 index 000000000..35d636f69 --- /dev/null +++ b/teavm-samples/teavm-samples-async/nbactions.xml @@ -0,0 +1,17 @@ + + + + build + + * + + + install + + + true + maven + + + + diff --git a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java index 598de3fb1..89ead77cf 100644 --- a/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java +++ b/teavm-samples/teavm-samples-async/src/main/java/org/teavm/samples/async/AsyncProgram.java @@ -48,6 +48,20 @@ public final class AsyncProgram { }, "Test Thread"); t.start(); + + Thread t2 = new Thread(new Runnable(){ + + @Override + public void run() { + try { + doRun(lock); + } catch (InterruptedException ex){ + System.out.println(ex.getMessage()); + } + } + + }, "Test Thread 2"); + t2.start(); System.out.println("Should be main -> Current thread is "+Thread.currentThread().getName()); System.out.println("Now trying wait..."); @@ -68,6 +82,12 @@ public final class AsyncProgram { Thread.sleep(5000); System.out.println("Current thread is "+Thread.currentThread().getName()); System.out.println("Finished another 5 second sleep"); + + synchronized(lock){ + System.out.println("Inside locked section of thread "+Thread.currentThread().getName()); + Thread.sleep(2000); + System.out.println("Finished locked section of thread "+Thread.currentThread().getName()); + } } private static void withoutAsync() { @@ -113,4 +133,6 @@ public final class AsyncProgram { System.out.println("Thread.yield called"); throw new IllegalStateException(); } + + }