Mutex: Difference between revisions
Content added Content deleted
(move the "Capability:" part into the template.) |
(→{{header|D}}: +clarification) |
||
Line 121: | Line 121: | ||
private: |
private: |
||
static num = 0; |
static num = 0; |
||
} |
|||
</lang> |
|||
Keep in mind that '''synchronized''' used as above works on a per-class-instance basis. |
|||
This is described in [[http://digitalmars.com/d/1.0/class.html##synchronized-functions|documentation]]. |
|||
The following example tries to illustrate the problem: |
|||
<lang D>import tango.core.Thread, tango.io.Stdout, tango.util.log.Trace; |
|||
class Synced { |
|||
public synchronized int func (int input) { |
|||
Trace.formatln("in {} at func enter: {}", input, foo); |
|||
// stupid loop to consume some time |
|||
int arg; |
|||
for (int i = 0; i < 1000*input; ++i) { |
|||
for (int j = 0; j < 10_000; ++j) arg += j; |
|||
} |
|||
foo += input; |
|||
Trace.formatln("in {} at func exit: {}", input, foo); |
|||
return arg; |
|||
} |
|||
private static int foo; |
|||
} |
|||
void main(char[][] args) { |
|||
SimpleThread[] ht; |
|||
Stdout.print( "Starting application..." ).newline; |
|||
for (int i=0; i < 3; i++) { |
|||
Stdout.print( "Starting thread for: " )(i).newline; |
|||
ht ~= new SimpleThread(i+1); |
|||
ht[i].start(); |
|||
} |
|||
// wait for all threads |
|||
foreach( s; ht ) |
|||
s.join(); |
|||
} |
|||
class SimpleThread : Thread |
|||
{ |
|||
private int d_id; |
|||
this (int id) { |
|||
super (&run); |
|||
d_id = id; |
|||
} |
|||
void run() { |
|||
auto tested = new Synced; |
|||
Trace.formatln ("in run() {}", d_id); |
|||
tested.func(d_id); |
|||
} |
|||
}</lang> |
|||
Every created thread creates its own '''Synced''' object, and because the monitor created by synchronized statement is created for every object, |
|||
each thread can enter the ''func()'' method. |
|||
To resolve that either ''func()'' could be done static (static member functions are synchronized per-class basis) or '''synchronized block''' should be used |
|||
like here: |
|||
<lang D> |
|||
class Synced { |
|||
public int func (int input) { |
|||
synchronized(Synced.classinfo) { |
|||
// ... |
|||
foo += input; |
|||
// ... |
|||
} |
|||
return arg; |
|||
} |
|||
private static int foo; |
|||
} |
} |
||
</lang> |
</lang> |