File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes K&B Chapter 9, Self Test 20 Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "K&B Chapter 9, Self Test 20" Watch "K&B Chapter 9, Self Test 20" New topic
Author

K&B Chapter 9, Self Test 20

Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391

What--if anything--can you add to the preceding code to ensure the integrity of data?
A. Synchronize the run method.
B. Wrap a synchronized(this) around the call to f.increase().
F. Synchronize the increase method.
A. is incorrect because synchronizing the run() method would stop other threads from running the run() method (a bad idea) but still would not prevent the other threads with other runnables from accessing the increase method.
B. is incorrect for virtually the same reason as A--synchronizing the code that calls the increase() method does not prevent other code from calling the increase() method.
F. is correct because synchronizing the code that actually does the increase will protect the code from being accessed by more than one thread at a time.
--------
I do not understand why A. and B. are incorrect, because...
Since data in Foo is private, the only way to access data is by calling increase().
The Foo object is referenced from an instance field of an anonymous class. It's not easy to get to fields of an anonymous class. The Foo object is a helper object of the anonymous class, created by the anonymous class.
The only way to invoke an instance method of Foo is by invoking a method of the class the anonymous class extends. In particular, the only way to invoke increase() is to invoke t.run().
Both the main thread and Thread-1 can invoke t.run(). If run() or a statement containing f.increase(); were synchronized, only one thread at a time, main or Thread-1, could invoke t.run().
Therefore, A. and B. would ensure the integrity of data.
[ August 08, 2003: Message edited by: Marlene Miller ]
Alton Hernandez
Ranch Hand

Joined: May 30, 2003
Posts: 443
Originally posted by Marlene Miller:

I do not understand why A. and B. are incorrect, because...
Since data in Foo is private, the only way to access data is by calling increase().
The Foo object is referenced from an instance field of an anonymous class. It's not easy to get to fields of an anonymous class. The Foo object is a helper object of the anonymous class, created by the anonymous class.
The only way to invoke an instance method of Foo is by invoking a method of the class the anonymous class extends. In particular, the only way to invoke increase() is to invoke t.run().
Both the main thread and Thread-1 can invoke t.run(). If run() or a statement containing f.increase(); were synchronized, only one thread at a time, main or Thread-1, could invoke t.run().
Therefore, A. and B. would ensure the integrity of data.
[ August 08, 2003: Message edited by: Marlene Miller ]

[/QB]

Hi Marlene,
I made a slight changes in the code which I think can corrupt that data in the instnace of Foo:
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Thank you Alton for thinking about my problem. A thread using another thread as a target. And then starting both of them. That's exotic.
I would not deny that when two threads execute run() concurrently, there can be a race condition.
The book says answers A. and B. are wrong. I was trying to explain why A. and B. are not wrong.
I thought it was interesting that the nature of an anonymous class in effect shields access to the object it has created and uses.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
It's a strange question. A and B only affect the integrity of the Foo instance f which is held by the anonymous Thread class in SyncTest's main() method. Well, the data held by that instance is never accessed after the increase() anyway, and no other threads or methods could possibly access it, so it's hard to see why it would matter whether that particular instance's data is safe or not. On the other hand, the Foo class is accessible to other classes in the package, so it's possible that some other code, not shown, is accessing a Foo instance - so it might be useful to ensure that any Foo instance is thread-safe. This can be ensured by F, but not A and B. However the way the code is written, no one can access Foo's private data varaible anyway, and there's no get() method, so again, what does it matter? It's hard to give a meaningful answer to this question without a better context. However, if you can agree that in general a method like F is liklier to be helpful (or, helpful in a wider variety of circumstnaces) than a method like A or B (assuming we had a context where the data variable is actually accessed by someone), then that's all the question was intended to get at.


"I'm not back." - Bill Harding, Twister
Marlene Miller
Ranch Hand

Joined: Mar 05, 2003
Posts: 1391
Thank you, Jim, for your thoughts.
and no other threads or methods could possibly access it

The main thread could access this particular instead of Foo. In the main method, we could add t.run() after t.start().
Also, since the main method has a reference to the Thread-1 object, if the main method gave that reference to another thread, that thread could invoke t.run().
So there is this one doorway to this particular Foo instance of this particular anonymous class, namely t.run().
what does it matter?

I am interested in the role of the anonymous class in this example. The Foo object is a helper object. No one can get to the object Foo except through the run() method.
Plus, I remember an example in Concurrent Programming in Java how Doug Lea does not synchronize the method that accesses the data. Instead, he synchronizes some method that calls the method that accesses the data.
Putting those two ideas together, I could see how one might choose to synchronize run() or a statement containing f.increase() instead of increase().
And maybe the Foo class is already defined and other people do not want it�s methods to be synchronized. But you want to use the Foo class.
I conclude that A. and B. are not incorrect.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: K&B Chapter 9, Self Test 20
 
Similar Threads
Question about the Thread / Synchronization --- SCJP mock Exam
Doubt in Threads
threads doubt
Threads and Synchronization examples
static context