@@ -1882,7 +1882,7 @@ void main()
1882
1882
$(H2 $(LEGACY_LNAME2 SynchronizedStatement, synchronized-statement, Synchronized Statement))
1883
1883
1884
1884
$(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.
1886
1886
)
1887
1887
1888
1888
$(GRAMMAR
@@ -1891,34 +1891,49 @@ $(GNAME SynchronizedStatement):
1891
1891
$(D synchronized $(LPAREN)) $(EXPRESSION) $(D $(RPAREN)) $(PSSCOPE)
1892
1892
)
1893
1893
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.
1901
1897
Different synchronized statements will have different global mutexes.
1902
1898
)
1903
1899
1904
1900
$(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.
1907
1904
The mutex used is specific to that Object instance, and
1908
1905
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.
1909
1909
)
1910
1910
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
+ )
1911
1933
$(P The synchronization gets released even if $(I ScopeStatement)
1912
1934
terminates with an exception, goto, or return.
1913
1935
)
1914
1936
1915
- $(P Example:
1916
- )
1917
-
1918
- --------------
1919
- synchronized { ... }
1920
- --------------
1921
-
1922
1937
$(P This implements a standard critical section.
1923
1938
)
1924
1939
@@ -1928,6 +1943,8 @@ synchronized { ... }
1928
1943
locked and unlocked as many times as there is recursion.
1929
1944
)
1930
1945
1946
+ $(P See also $(DDSUBLINK spec/class, synchronized-classes, synchronized classes).)
1947
+
1931
1948
$(H2 $(LEGACY_LNAME2 TryStatement, try-statement, Try Statement))
1932
1949
1933
1950
$(P Exception handling is done with the try-catch-finally statement.)
0 commit comments