From: markspace on
www wrote:

> This is equal to running my program in single thread. Am I correct?


Not really, no. The synchronized keyword provides different semantics
than just "single threaded behavior," whatever that might mean.


> More specifically, how can I make sure that checkSomething() is finished
> at the top of doThis()?


Using synchronized as shown will do that. This is called MUTEX ("mutual
exclusion") and is one of the semantics "synchronized" provides, but not
the only one.

Hint: Google MUTEX.


From: Lew on
Jim Janney wrote:
>> The simplest and least error prone approach is to declare both methods
>> as synchronized, e.g.
>
>>     synchronized public void doThis()
>
>>     synchronized public void checkSomething()
>

www wrote:
> This is equal to running my program in single thread. Am I correct?
>

What do you mean by "equal"? It's not the same as running in a single
thread, no, and nor is it always going to be enough for every
concurrent situation. Whether it's as safe as running in a single
thread depends on the details of the situation, but for this simple
situation it seems to be. Pete alluded to risks with this approach
upthread.

> More specifically, how can I make sure that checkSomething() is finished
> at the top of doThis()?
>

With the simple approach shown, you can be sure that
'checkSomething()' and 'doThis()' are not executing simultaneously
within the same instance.

You need to learn to think in terms of concurrent programming, which
takes a bit of time. One trick is to think in terms of "critical
sections". Those are parts of code that access the same data, so in a
concurrent environment they can interfere with each other unless
you're careful. To be careful, you apply 'synchronized' or 'volatile'
or a raft of other techniques. A critical section is a shortest piece
of code that operates on the shared data as a unitary operation. The
collection of critical sections is the collection of pieces of code
that have to honor the same synchronization mechanism.

By the way, this is for read or write. You cannot synchronize on,
say, just the write sections and expect unsynchronize read sections to
work correctly.

Another trick is to master the Java concept of /happens-before/. This
is the set of rules about what changes threads can see that were made
by other threads. It's a good trick because once you get the concept,
you can reason about whether changes will be visible or conflict
between threads.

--
Lew
From: markspace on
www wrote:
> The code below is completely fine if running on single-thread
> environment. But it could break if running on multi-thread environment.

> public class MyClass
> {
> private Person tim = new Person("Tim");
> private Person tom = new Person("Tom");
>


Here's a weird question for this list at large. Are the above lines
even thread safe? Objects are guaranteed to be correctly constructed,
but these objects might be mutable. And the fields tim and tom are not
final, so they aren't guaranteed to be published correctly either.

So one thread has to construct this "MyClass" and then some other thread
might consume it (note that the methods of MyClass are not static, so an
instance does have to be constructed):

public class Main {
public static void main( String... args ) {
MyClass test = new MyClass();
... // now what?
}
}

So here if one then passed the "test" object to, for example, the EDT
for use in a GUI, one still needs synchronization/happens-before to make
the "test" object correctly visible to the EDT, or any other thread
besides main, yes?

I could look this up but I'm feeling a bit lazy right now, and I thought
the OP could use some discussion of other thread-safe semantics besides
mutex, which is the only one he seems to understand right now.
From: Jim Janney on
www <www(a)nospam.com> writes:

> Jim Janney wrote:
>
>>
>> The simplest and least error prone approach is to declare both methods
>> as synchronized, e.g.
>>
>> synchronized public void doThis()
>>
>> synchronized public void checkSomething()
>>
>
> This is equal to running my program in single thread. Am I correct?
>
> More specifically, how can I make sure that checkSomething() is
> finished at the top of doThis()?

Assume that there is an instance of MyClass and that some thread is
executing in either doThis() or checkSomething() on that instance.
The synchronized declaration accomplishes two things:

1) If any other thread tries to execute doThis() or checkSomething()
on the same instance, it will block until the first thread exits
the synchronized method it's in, either by returning normally or by
throwing an exception.

2) By the time the blocked thread is allowed to enter, any changes to
the object made by the previous thread will be visible in memory to
the second thread.

In other words, it guarantees both exclusion and memory consistency.

--
Jim Janney



From: Peter Duniho on
markspace wrote:
> www wrote:
>> The code below is completely fine if running on single-thread
>> environment. But it could break if running on multi-thread environment.
>
>> public class MyClass
>> {
>> private Person tim = new Person("Tim");
>> private Person tom = new Person("Tom");
>>
>
>
> Here's a weird question for this list at large. Are the above lines
> even thread safe? Objects are guaranteed to be correctly constructed,
> but these objects might be mutable. And the fields tim and tom are not
> final, so they aren't guaranteed to be published correctly either.
>
> So one thread has to construct this "MyClass" and then some other thread
> might consume it (note that the methods of MyClass are not static, so an
> instance does have to be constructed):
>
> public class Main {
> public static void main( String... args ) {
> MyClass test = new MyClass();
> ... // now what?
> }
> }
>
> So here if one then passed the "test" object to, for example, the EDT
> for use in a GUI, one still needs synchronization/happens-before to make
> the "test" object correctly visible to the EDT, or any other thread
> besides main, yes?

For the EDT example, there are actually two different mechanisms that
should ensure thread safety. One of them, I would have to look up to
make sure is supported in the JVM (but I'm pretty sure it is). The
other is inherent in your statement "passed the 'test' object to�the EDT".

The first mechanism has to do with semantics surrounding object
construction. In .NET, the specification ensures that whatever happens
in the constructor "happens before" any other code that uses the
reference after the constructor completes (.NET doesn't actually use the
term "happens-before", but it's the same idea). I would expect Java to
be the same in this respect.

Note that this is a good reason for not letting the "this" reference
leak out of the constructor, because doing so would circumvent whatever
assurances the object construction semantics would normally provide.

The second mechanism has to do with how object references get from one
thread to another. In particular, keep in mind that "happens
before"/"happens after" has a sort of transitive nature to it.
Everything that happens before something synchronized in one thread is
visible to everything that happens after the inspection of that
synchronized something in a different thread.

In the case of the EDT, the typical way an object reference would get
from another thread to the EDT is via the invokeLater() or
invokeAndWait() methods. These methods are inherently synchronized
themselves; it's a natural consequence of what must happen for the data
passed to the methods to get to the EDT.

This means that everything that happened in that other thread before the
call to invokeLater() or invokeAndWait() is necessarily going to be
visible to the EDT, as long as it only inspects that data as a result of
whatever Runnable was passed to the invoke�() method. Likewise if the
data was passed not via an invoke�() method but rather via, for example,
a synchronized queue monitored by a Swing timer that inspects it
periodically. All bets are off, of course, if the data is transferred
via some unsynchronized means.

This applies more generally to any cross-thread communication mechanism.
Even if not using the EDT, there is likely some synchronized
data-transfer mechanism that acts as the go-between, allowing that newly
constructed reference to safely move from one thread to the other. So
long as the reference is not inserted into that synchronized mechanism
until the constructor returns, then the other thread has the full
guarantee of the object being fully initialized that the original thread
where the object was created has.

In other words, even if it turns out that I'm mistaken and the JVM
doesn't provide any specific synchronization guarantees with respect to
object construction, code that is otherwise thread-safe anyway will
automatically ensure that the initialization of the object is itself
thread-safe.

Note also that this second mechanism applies not just to construction,
but to _any_ mutation that may occur in one thread prior to the object
being delivered to another thread.

Finally, part of your question brings up the possibility of the "Person"
object being mutable. And well, yes. If those classes are mutable,
there could yet still be a thread-safety problem if they mutate
post-construction without synchronization being used between threads
handling those objects. But that's not related to the question of the
initialization of the object. That would be just the usual "synchronize
mutations" problem that generally comes up with concurrent code.

Pete