Skip to content

Commit d50330a

Browse files
authored
[spec] Improve SynchronizedStatement docs (#3739)
Reword. Add example and explain difference between unique and object mutexes.
1 parent 1a3099c commit d50330a

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

spec/statement.dd

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,7 +1882,7 @@ void main()
18821882
$(H2 $(LEGACY_LNAME2 SynchronizedStatement, synchronized-statement, Synchronized Statement))
18831883

18841884
$(P The synchronized statement wraps a statement with
1885-
a mutex to synchronize access among multiple threads.
1885+
mutex locking and unlocking to synchronize access among multiple threads.
18861886
)
18871887

18881888
$(GRAMMAR
@@ -1891,34 +1891,49 @@ $(GNAME SynchronizedStatement):
18911891
$(D synchronized $(LPAREN)) $(EXPRESSION) $(D $(RPAREN)) $(PSSCOPE)
18921892
)
18931893

1894-
$(P Synchronized allows only one thread at a time to execute
1895-
$(I ScopeStatement) by using a mutex.
1896-
)
1897-
1898-
$(P What mutex is used is determined by the *Expression*.
1899-
If there is no *Expression*, then a global mutex is created,
1900-
one per such synchronized statement.
1894+
$(P A synchronized statement without *Expression* allows only one thread
1895+
at a time to execute $(I ScopeStatement) by locking a mutex.
1896+
A global mutex is created, one per synchronized statement.
19011897
Different synchronized statements will have different global mutexes.
19021898
)
19031899

19041900
$(P If there is an *Expression*, it must evaluate to either an
1905-
Object or an instance of an $(I Interface), in which case it
1906-
is cast to the Object instance that implemented that $(I Interface).
1901+
Object or an instance of an $(DDLINK spec/interface, Interfaces, interface),
1902+
in which case it
1903+
is cast to the Object instance that implemented that interface.
19071904
The mutex used is specific to that Object instance, and
19081905
is shared by all synchronized statements referring to that instance.
1906+
If the object's mutex is already locked when reaching the synchronized
1907+
statement, it will block every thread until that mutex is unlocked by
1908+
other code.
19091909
)
19101910

1911+
$(PANEL
1912+
$(SPEC_RUNNABLE_EXAMPLE_COMPILE
1913+
---
1914+
void work();
1915+
1916+
void f(Object o)
1917+
{
1918+
synchronized (o) work();
1919+
}
1920+
1921+
void g(Object o)
1922+
{
1923+
synchronized (o) work();
1924+
}
1925+
---
1926+
)
1927+
$(P If `f` and `g` are called by different threads but with the same
1928+
argument, the `work` calls cannot execute simultaneously. If the
1929+
`(o)` part of the `synchronized` statements is removed in one
1930+
or both functions, then both `work` calls could execute
1931+
simultaneously, because they would be protected by different mutexes.)
1932+
)
19111933
$(P The synchronization gets released even if $(I ScopeStatement)
19121934
terminates with an exception, goto, or return.
19131935
)
19141936

1915-
$(P Example:
1916-
)
1917-
1918-
--------------
1919-
synchronized { ... }
1920-
--------------
1921-
19221937
$(P This implements a standard critical section.
19231938
)
19241939

@@ -1928,6 +1943,8 @@ synchronized { ... }
19281943
locked and unlocked as many times as there is recursion.
19291944
)
19301945

1946+
$(P See also $(DDSUBLINK spec/class, synchronized-classes, synchronized classes).)
1947+
19311948
$(H2 $(LEGACY_LNAME2 TryStatement, try-statement, Try Statement))
19321949

19331950
$(P Exception handling is done with the try-catch-finally statement.)

0 commit comments

Comments
 (0)