Вы находитесь на странице: 1из 7

6/12/13

About thread safe... (SCJD forum at JavaRanch)

Big Moose Saloon


A friendly place for programming greenhorns!
Search

Java FAQ

Recent Topics

Register / Login

A special promo: Enter your blog post or vote on a blogger to be featured in an upcoming Journal

JavaRanch Java Forums Certification Developer Certification (SCJD/OCMJD)

Author

About thread safe...


posted 10/9/2002 9:31 PM

Sandra Baker Greenhorn Joined: Jul 10, 2002 Posts: 26

(Edited the original post.....) I used this data structure to store my locked record number, do I need to synchronize the object? private static SortedSet lockedRec = Collections.synchronizedSortedSet(new TreeSet()); Here is how it works: Clients need to check if the record number is currently in the lockedRec, if not, can lock the record. If yes, use while loop to try certain amount of times ( i set it to be 100 sec), after this amount of time, there may be something wrong with the client who's currently locking this record, then, explicitly unlock the record by the server. [ October 09, 2002: Message edited by: Sandra Baker ]

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/9/2002 9:40 PM

Hi Sandra, You're almost there: Everything is right, except for the following: 1) you need to explicitly synchronize on your SortSet in the lock/unlock methods, using a while loop: for example...
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 .

p u b l i cv o i dl o c k ( ) { s y n c h r o n i z e d ( m y S o r t e d S e t ) { / / s t u f f S o r t e d S e t . n o t i f y A l l ( ) ; }

2. Given the above, there is absolutely no need to use a synchronized collection. I seem to recall that you said you had purchased my book. I thought I laid this out pretty explicitly there. Didn't I? I hope it doesn't sound like I'm chastising you: I just want to make sure I was clear. All best, M, author The Sun Certified Java Developer Exam with J2SE 1.4 [ October 09, 2002: Message edited by: Max Habibi ]

Java Regular Expressions

Mark Spritzler ranger Sheriff Joined: Feb 05, 2001

posted 10/9/2002 9:45 PM

C lients need to check if the record number is currently in the lockedRec, if not, can lock the record. If yes, use while loop to

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

1/7

6/12/13
2001 Posts: 17243

C lients need to check if the record number is currently in the lockedRec, if not, can lock the record. If yes, use while loop to try certain amount of times ( i set it to be 100 sec), after this amount of time, there may be something wrong with the client who's currently locking this record, then, explicitly unlock the record by the server.

About thread safe... (SCJD forum at JavaRanch)

1
I like...

Doesn't quite make sense to me here. Why have a time limit or a limited number of loops, that is not in the requirments. So then you automatically unlock the record just because it is possible that there is something wrong with the client? All you need is a HashSet to store the locked records. when you call lock amke sure you use synchronize(<<HashSet>> { } and have your code try to get the lock using a while loop. and issueing a wait() if the record is locked by another user. Then use the Unreferenced interface to handle your possible something wrong with the client issue, where in the Unreferenced method you unlock the records that client has. This is nice and clean there is complete Thread Safety there in the HashSet when you synchronize on it, and wait if it is already locked. You will find many posts on this approach, and that will get you the full amount of points. Petitioning, unfortunately won't help in this case. Sorry. Mark

Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer How to Ask Questions the Smart Way FAQ

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/9/2002 10:10 PM

I just reread your post: Mark is absolutely right, drop this whole business of looping to a hundred. Here's how synchronization works. When you say
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 .

1 :s y n c h r o n i z e d ( m y O b j ) { 2 : 3 :w h i l e( m y O b j . c o n t a i n s ( n u m )& &! i s O w n e r ( n u m ) )m y O b j . w a i t ( ) 4 : 5 :m y O b j . n o t i f y A l l ( ) ; 6 :}

what you're saying on line 1 is: "Hey, only let a single given thread -call him LuckyThread- use myObj right now. Tell all other Threads-Call them UnLuckyThreads- that want to use myObj to cool their heels for a bit.". So now LuckyThread starts to execute, and he reaches line number 3. Say LuckyThreadwants to put 99 into myObj, but MyObj already has a 99. So what does LuckyThread do? He waits. He say "Geez, I can't do what I wanted to, so why don't you guys(UnLuckyThreads- ) enter a lottery and see who gets to be the next LuckyThread?". The unLuckys do, and a new LuckyThread is elected. Say she wants to remove 99 from myObj. When the new LuckyThread reaches line 5, she says to all of those unlucky Threads. "Ok, I'm done with myObj now, and I'm outta here. Why don't you guys enter a lottery and see who gets to be the next LuckyThread?". And that's what those UnLucky threads do. So we get a new LuckyThread, and the cycle starts again. All best, M, author The Sun Certified Java Developer Exam with J2SE 1.4 [ October 09, 2002: Message edited by: Max Habibi ]

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/9/2002 10:35 PM

I hope that clear it up. If not, you're welcome to drop down to your local BN and read chapter 4: it should only take an hour or so. If they give you any trouble, tell'em I said it was ok All best, M, author The Sun Certified Java Developer Exam with J2SE 1.4 .

christy smile Ranch Hand Joined: Oct 15, 2001 Posts: 101

posted 10/9/2002 11:27 PM

Hi, Mark, Max I have a question about synchronized and HashMap vs. HashSet. I made my lock() and unlocked() synchroinzed functions so that I don't have to worry about synchronizing the HashMap I used to store the recordNumber and the corresponding object that has locked that record. Is this the right approach as well? In addition, I chose HashMap instead of HashSet to store the record and object pair. Is there is big advantage of using

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

2/7

6/12/13

About thread safe... (SCJD forum at JavaRanch)


In addition, I chose HashMap instead of HashSet to store the record and object pair. Is there is big advantage of using HashSet? Or which one is better? Thanks, Christy

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/10/2002 12:16 AM

Christy, Just because your lock method is synchronized doesn't mean that you're threadsafe. Remember, since the HashMap is static, it's not an instance variable. That means the several distinct threads could still modify at the same time. Since you've decided to change the method signatures anyway, you're better off making lock static synchronized: then this issue goes away. all best, M, author The Sun Certified Java Developer Exam with J2SE 1.4

Mark Spritzler ranger Sheriff Joined: Feb 05, 2001 Posts: 17243

posted 10/10/2002 12:54 AM

Like Max said, the best way to secure threadsafety for your HashSet, is to synchronize on it, and then check for the locked record in the HashSet in the while statement, if it is there issue a wait(), having a Try Catch around it, catching the InterruptedException, and going about your businesss, cause now you can call put to the HashSet and lock the record for the client. then the synchronization section is ended. Mark

1
I like...

Venita Glasfurd Greenhorn Joined: Sep 11, 2002 Posts: 12

posted 10/10/2002 1:56 AM

and then check for the locked record in the HashSet in the while statement

Why check for a locked record in a while statement? I have used an if statement to check for a locked record. My implementation goes like this.

view plain

c opy to c lipboard

print

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 .

s y n c h r o n i z e d ( m y L o c k T a b l e ) { i f( m y L o c k T a b l ec o n t a i n sr e c o r dn u m b e rt ob el o c k e d ) { w a i t } p u tr e c o r dn u m b e ri nm y L o c k T a b l e }

I cannot visualise a situation where a while loop is required. Am I missing something obvious here? Venita

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/10/2002 2:22 AM

It's not obvious, but there's a good reason to use a while statement. It has to do with the way that while statements interact with Threads. Even in a synchronized block, your thread can be switched out. However, when your thread switches back in, a while-condition is immediately check again, first thing. An if-statement is not. That why a block like
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

0 1 .

1 :w h i l e ( c o n d i t i o n ) {

3/7

6/12/13
0 1 . 0 2 . 0 3 . 1 :w h i l e ( c o n d i t i o n ) { 2 : w a i t ( ) ; 3 :}

About thread safe... (SCJD forum at JavaRanch)

is valid. It gets tested every time the thread slices in. An if-statement just does not. HTH, M, author The Sun Certified Java Developer Exam with J2SE 1.4
Venita Glasfurd Greenhorn Joined: Sep 11, 2002 Posts: 12

posted 10/10/2002 2:47 AM

Thanks, Max. I've got it. Venita.

christy smile Ranch Hand Joined: Oct 15, 2001 Posts: 101

posted 10/10/2002 2:49 AM

Hi, Mark, Max, Thank you for your comments about synchronization. I have another question about the lock()/unlock. For my current implementation, I have a DataLockManager associated with every remote client (I do not have any locking mechanism for the local client). In DataLockManager, I have a function called lockDB, which sets the "dblock" flag, similar to the following quote I found the in a previous posting:

You can do it either way. There are two schools of thought on locking the whole database: loop through all the records and lock them (this was Mark's approach); set a "dblock" flag, that when set, will not allow any further records to be locked and wait for all pending locks to be unlocked at which time the dblock is established (this was my and I believe Nate's and Eugene's approach).

My question is: (1) Should I make the flag dblock static? Since I have multiple instances DataLockManager, but if one client locks the whole database, every client should know about it. (2) Someone suggested in a different thread that the LockManager should be made singleton. Is this necessary if I have both my HashMap and the flag static? (3) This one goes back to the synchronization issue. If I want ot synchronize on only the object, don't I need to synchronize both the HashMap and "dblock" flag in my lock()? The following is the code for my current lock() in DataLockManager (I have not changed the synchronization yet). By the way, I am bypassing the lock()/unlock in Data class completely. Do you think that's okay? The ClientId is the connection object.
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 . 2 5 . 2 6 . 2 7 . 2 8 . 2 9 . 3 0 . 3 1 .

p u b l i cs y n c h r o n i z e dv o i dl o c k ( S t r i n gc l i e n t I D ,i n tr e c o r d N o )t h r o w sR e m o t e E x c e p t i o n ,I O E x c e p t i o n { i f(r e c o r d N o<1| |r e c o r d N o>m D B . g e t R e c o r d C o u n t ( )) t h r o wn e wI O E x c e p t i o n ( " R e c o r dD o e sN o tE x i s t " ) ; / / l o c k st h ew h o l ed a t a b a s e i f(r e c o r d N o= =1) { l o c k D B ( ) ; r e t u r n ; } I n t e g e rr e c O b j=n e wI n t e g e r ( r e c o r d N o ) ; S t r i n gl o c k C l i e n t I D=( S t r i n g ) m L o c k R e c o r d s . g e t ( r e c O b j ) ; / / t h er e c o r dh a sb e e nl o c k e db yt h es a m ec l i e n t ,d on o t h i n g i f(l o c k C l i e n t I D ! = n u l l& &l o c k C l i e n t I D . e q u a l s ( c l i e n t I D )) r e t u r n; / / l o c kt h er e c o r db yp l a c i n gt h ec l i e n t I da n dr e c o r d N oi n t ot h eh a s h t a b l e i f(l o c k C l i e n t I D= =n u l l& &! m D B L o c k e d) { m L o c k R e c o r d s . p u t (r e c O b j ,c l i e n t I D ) ; } e l s e { w h i l e(m L o c k R e c o r d s . g e t (r e c O b j)! =n u l l| |m D B L o c k e d) { t r y { w a i t ( ) ; } c a t c h(E x c e p t i o ne) {

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

4/7

6/12/13
3 1 . 3 2 . 3 3 . 3 4 . 3 5 . 3 6 . 3 7 . { }

About thread safe... (SCJD forum at JavaRanch)


t h r o wn e wI O E x c e p t i o n( U N E X P E C T E D+e . g e t M e s s a g e ( ) ) ; } m L o c k R e c o r d s . p u t (r e c O b j ,c l i e n t I D) ; } }

Thanks. Christy

christy smile Ranch Hand Joined: Oct 15, 2001 Posts: 101

posted 10/10/2002 2:51 AM

By the way, mDBLocked is the "dblock" flag and mLockRecord is the static HashMap. Currently, the mDBLocked is just a boolean variable. I am thinking about changing it to static as well. Comments welcome! Christy

Daniel Chen Greenhorn Joined: Oct 07, 2002 Posts: 24

posted 10/10/2002 7:33 AM

Hi Max, Why need notifyAll at the end of your method? [ October 09, 2002: Message edited by: Daniel Chen ]

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/10/2002 7:38 PM

Hi Danial, NotifyAll tell every Thread that is waiting that the resource in now free. HTH, M, author The Sun Certified Java Developer Exam with J2SE 1.4

Mark Spritzler ranger Sheriff Joined: Feb 05, 2001 Posts: 17243

posted 10/10/2002 8:25 PM

Christy you are very close. "static? Since I have multiple instances DataLockManager" No you do not need to make it static and I suggest you don't. You should only have one instance of the DataLockManager, and it shouldn't be a Singleton though. Like you create one instance of the Data class, you will also have only one LockManager created, which every Client Remote Object should have a reference too, not a seperate instance created in each. That actually should answer all three of your questions.

1
I like...

Sandra Baker Greenhorn Joined: Jul 10, 2002 Posts: 26

posted 10/10/2002 8:27 PM

Here is my lock and unlock.... please give me some feedback, I am kinda skeptical about two synchronized (myobj) in the lock...Thanks
view plain c opy to c lipboard print ?

N ote: T ext c ontent in the c ode bloc ks is automatic ally word- wrapped

0 1 . 0 2 . 0 3 . 0 4 . 0 5 . 0 6 . 0 7 . 0 8 . 0 9 . 1 0 . 1 1 . 1 2 . 1 3 . 1 4 . 1 5 . 1 6 . 1 7 . 1 8 . 1 9 .

/ / m y O b js t o r e st h el o c k e dr e c o r dn u m b e r s p r i v a t es t a t i cS e tm y O b j=C o l l e c t i o n s . s y n c h r o n i z e d S e t ( n e wH a s h S e t ( ) ) ; p u b l i cv o i dl o c k ( r e c o r d N u m )t h r o w sR e m o t e E x c e p t i o n ,I O E x c e p t i o n { t r y { s y n c h r o n i z e d ( m y O b j ) { w h i l e ( m y O b j . c o n t a i n s ( r e c o r d N u m )= =t r u e ) { / / n o t i f y A l l ,r e l e a s et h em o n i t o ro ft h eo b j e c tf o ro t h e r s / / w a i t } } } c a t c h( I n t e r r u p t e d E x c e p t i o ni e ) { S y s t e m . o u t . p r i n t l n ( i e ) ; } } s y n c h r o n i z e d ( m y O b j ) { / / a d dr e c o r d / / n o t i f y A l l } p u b l i cv o i du n l o c k ( r e c o r d N u m )t h r o w sR e m o t e E x c e p t i o n { s y n c h r o n i z e d ( m y O b j ) {

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

5/7

6/12/13

1 9 . 2 0 . 2 1 . 2 2 . 2 3 . 2 4 .

s y n c h r o n i z e d ( m y O b j ) { / / r e m o v er e c o r d / / n o t i f y A l l } }

About thread safe... (SCJD forum at JavaRanch)

[ October 10, 2002: Message edited by: Sandra Baker ]

Max Habibi town drunk ( and author) Sheriff Joined: Jun 27, 2002 Posts: 4118

posted 10/10/2002 11:50 PM

You're very, very close. However, you can't just call wait: you need to call wait on myObj. here's why: When you wait(), you are, of course, really calling this.wait(). But the this object isn't the one you're synchronizing on: you're synchronizing on myObj. I've posted on this before, in a great deal of detail, so you might want to do a search on my posts if you still have some questions. The same is true for notifyAll(). All best, M, author The Sun Certified Java Developer Exam with J2SE 1.4

christy smile Ranch Hand Joined: Oct 15, 2001 Posts: 101

posted 10/11/2002 1:03 AM

Hi, Mark, Max, Thank you for the reply. I went back to my lock() and unlock() again just to familiarize myself (I did most of the SCJD coding about 6 months ago, and slept on it for almost half year, and determined finally to finish the exam by the end of this month hopefully. For the ranchers out there, please don't laught me at this ). Anyway, I realized that I misrepresented something in the previous post. For each Data Server, there is actually only one DataLockManager instance associated (no matter how many clients are connected with the server). Question #1: Given that, I don't even need to make my HashMap that stores the recordId and clientId pair static anymore, right?

You should only have one instance of the DataLockManager, and it shouldn't be a Singleton though. Like you create one instance of the Data class, you will also have only one LockManager created, which every C lient Remote Object should have a reference too, not a seperate instance created in each.

[B]Question #2: Did not quite understand the above quote. I should only have one DataLockManager for each DataServer I create (each DataServer is in term associated with a Data file), right? But what if I have multiple data servers started with the same data file, I still only should have one DataLockManager associated with that Data file. Then, how am I going to keep track? As far as my current implementation goes, if server#1 and Server#2 decided to serve the same database, then, DataLockManager#1 and DataLockManager#2 is created respectively. If the HashMap is static, that's okay. But I am thinking about changing the HashMap to just a member variable. Since if it is static, what if Server#1 and Server#2 started on different data file, the HashMap will be shared by different data files, which is not correct at all. What do you think about that? [B]Question #3, if both HashMap and the dblocked flag are not static, should I use synchronized on the whole function? What is the advantage of only synchronizing on the HashMap. In addition, in my code where i have "wait()", according to Max's comment, shouldn't I use "mLockedRecord.wait()" as well if I just synchronize on mLockedRecord. I hope I am making sense here. Thanks. Christy

I agree. Here's the link: http://aspose.com/file-tools

subject: About thread safe...

Similar Threads My Locking Method: please, advise me. Thread safe? unlock method

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

NX: My Locking Mechanism

6/7

6/12/13

About thread safe... (SCJD forum at JavaRanch)


NX: My Locking Mechanism NX: cacheless design to keep things simple?
All times above are in your local time zone & format.T he current ranch time (not your local time) is Jun 12, 2013 07:43:00 .

Contact Us | Powered by JForum |

C opyright 1998-2013 Paul W he aton

www.coderanch.com/t/182138/java-developer-SCJD/certification/thread-safe

7/7

Вам также может понравиться