aspose file tools*
The moose likes Threads and Synchronization and the fly likes How to block access based on elements existance? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "How to block access based on elements existance?" Watch "How to block access based on elements existance?" New topic
Author

How to block access based on elements existance?

Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
I'll try to describe as good as I can.

There is a:
private static Set<String> UUIDsInUse = Collections.synchronizedSet(new HashSet<String>());

What I would like to do is to execute certain method if there isn't a certain String in the set (the method that is about to execute will add that String to the set for the time of execution).
I do not even know IF using a set to synchronize this is a good idea. I am like so clueless about that (and google is not helping, because of ambiguity of keywords).

I thought of using BlockingQueue (I just found this on google, so I don't know if it's good either) but then, if the static method calls the BlockingQueue and it gets blocked then it's bad too (the class has only static methods)

I also thought of some super dirty solution (but working) - to make 10 functions exactly the same (that's a whole lot of redundant code) the same and store which function is used with which element in the Set, but having 10 functions exactly the same is I guess very ugly solution (and what happens if there are more than 10 elements in the set?)

Any help appreciated.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:I'll try to describe as good as I can.

There is a:
private static Set<String> UUIDsInUse = Collections.synchronizedSet(new HashSet<String>());

What I would like to do is to execute certain method if there isn't a certain String in the set (the method that is about to execute will add that String to the set for the time of execution).


If I understand your requirements, (and I'm not sure I do), then the simplest approach is

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:I thought of using BlockingQueue (I just found this on google, so I don't know if it's good either) but then, if the static method calls the BlockingQueue and it gets blocked then it's bad too


So call a non-blocking method, or one with a timeout.

(the class has only static methods)


Bad idea, but not relevant to anything you've said as far as multithreading goes.
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Jeff Verdegan wrote:
If I understand your requirements, (and I'm not sure I do), then the simplest approach is



As far as I understand the synchronized set means that 2 threads can't add an element at the same time (or to edit the set for that matter) but it doesn't mean that if the element is already in the set it will wait for the moment when it isn't. So the 2nd call to add same element will simply be ignored (that's why it's a Set not a List). I don't see how that would work...
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
Jeff Verdegan wrote:
If I understand your requirements, (and I'm not sure I do), then the simplest approach is



As far as I understand the synchronized set means that 2 threads can't add an element at the same time (or to edit the set for that matter)


All the public methods are synchronized. So any call that one thread makes will run to completion before any call that any other thread can make.

but it doesn't mean that if the element is already in the set it will wait for the moment when it isn't.


I never said or even implied it would, and your requirements didn't say anything about that.

So the 2nd call to add same element will simply be ignored (that's why it's a Set not a List). I don't see how that would work...


Have you looked at the docs for what add() returns? What do you think that if statement is for?
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
But if the element already is in the list the above code snippet will not make it wait till it isn't, which is like ummm the whole point of it.

I'll try to rephrase what I want:
I want a method to be called only if some_requirements are met and if they are not then wait till they are (I really made it clear earlier).
.. but....
I want to achieve this with a static method - so the method can't be blockable. And if my static method is not synchronized but it spawns synchronized method then if that method get's blocked then it's parent gets blocked and since the parent is static I won't be able to call it again. That's why there was a dirty solution presented by me to have 10 super exact same functions with different name so I could call different function every time.


The synchronized set was just an idea. I don't need to keep clinging to it by all costs.

--
edit: I spend another 2 hours googling + thinking about this, yet no solution came to me.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18675
    
    8

Justin Thomas wrote:I want a method to be called only if some_requirements are met and if they are not then wait till they are (I really made it clear earlier).


I didn't find it all that clear. I expect that was because you're just waving your hands about "some requirements". If you give me a real-life situation I expect I would find it much easier to discuss that.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:But if the element already is in the list the above code snippet will not make it wait till it isn't, which is like ummm the whole point of it.


This is the first time you've stated that that's part of your requirements.

I'll try to rephrase what I want:
I want a method to be called only if some_requirements are met and if they are not then wait till they are.
.. but....


That's easy enough, but the thread that's waiting for the requirements so that it can call the method can't be the same thread that's realizing the requirements. In other words, thread T1 comes in, checks for those requirements, and if they're true, executes the method, and if not, it stops and waits until thread T2 makes them true.

If that's what you want, then you can sync on the set, then in a loop check for the existence of that element, if it's there (or not there--whichever is your "keep waiting" condition), then call wait(). When you return from the wait(), go back to the test. Once the test passes, you break out of the loop.

There are also constructs in java.util.concurrent that might be useful here, such as a CountdownLatch. However, I'd recommend figuring out how to do it with these lower level operations first, to make sure you understand the concepts.

I want to achieve this with a static method - so the method can't be blockable.


You shouldn't care if the method is static or not. If you do, you may have a design flaw. However, even if the method is static, as I said before, that has no bearing on your threading issues.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
I'll try to rephrase what I want:
I want a method to be called only if some_requirements are met and if they are not then wait till they are (I really made it clear earlier).


No, you really, really didn't.
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Version 1



Version 2


Version 3


All fail.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:Version 1


Like I said:

1) Static or not has nothing to do with the problem at hand.

2) sync, while, wait()
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Jeff Verdegan wrote:
There are also constructs in java.util.concurrent that might be useful here, such as a CountdownLatch. However, I'd recommend figuring out how to do it with these lower level operations first, to make sure you understand the concepts.


I
Found this: http://onjava.com/onjava/excerpt/jthreads3_ch6/index1.html
Looks scary and is hell'a complicated.

II
Spawning another thread is pointless, because no matter how many threads there are if the method is static (and synchronized?) it will still be called only once. And spawning threads without a reason is more ugly than 10 redundant functions.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18675
    
    8

Yeah, a binary Semaphore might do it. Whatever is meeting those mysterious requirements would call release() on it, and whatever is waiting for them to be met would call acquire() on it.
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Jeff Verdegan wrote:
Justin Thomas wrote:Version 1


Like I said:

1) Static or not has nothing to do with the problem at hand.

2) sync, while, wait()


1. It has everything to do with it. Otherwise every object could spawn wait for itself

2. wait() also implies there will be somewhere notify() and how would a certain function now if it conerns that instance of this function and not something other. So it would require to overwrite wait() and notify() in a manner consistent with what must be done and since same "idea" would be used to write any other code that would do just the same then using wait() is pointless.
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Rephrasing again (for simplicity reasons):

1. You are at supermarket. And there are clients and cashiers. (You are client)
2. If you buy a green product you go to a green cashier. If you buy blue you go to blue one
3. One cashier can be handling only 1 customer at a time
4. Number of colors is unknown from beforehand
5. You (an object) can't move, the supermarket itself (static) moves you to a correct queue if you rise your hand.

I really don't know how to rephrase it any simpler :( :( :( :(
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
II
Spawning another thread is pointless, because no matter how many threads there are if the method is static (and synchronized?) it will still be called only once. And spawning threads without a reason is more ugly than 10 redundant functions.


You're completely missing the point. There *have* to be at least to threads for what you want to do, and nobody said you have to make the method synchronized. And since when are static methods "only called once"?

You seem to have some fundamental confusions that need clearing up.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
Jeff Verdegan wrote:
Justin Thomas wrote:Version 1


Like I said:

1) Static or not has nothing to do with the problem at hand.

2) sync, while, wait()


1. It has everything to do with it.


No, it does not.

Otherwise every object could spawn wait for itself


That sentence doesn't actually mean anything.

2. wait() also implies there will be somewhere notify()


Of course. The thread that completes the conditions that you mentioned would call notify().

and how would a certain function now if it conerns that instance of this function and not something other.


Eh? No idea what you're saying here.



So it would require to overwrite wait() and notify() in a manner consistent with what must be done and since same "idea" would be used to write any other code that would do just the same then using wait() is pointless.


No. If you want to wait until a certain condition is true before proceeding, then the wait() method is one very appropriate way to it, and is in fact viable in almost all cases (though not necessarily optimal since the arrival of the java.util.concurrent packages). All I can say at this point is that you either need to brush up on thread fundamentals, or you need to to a lot better job of explaining your problem. Possibly both.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18675
    
    8

So each cashier is a queue. A BlockingQueue might be okay. When the cashier needs to serve the next customer, it calls take() on the queue to get one, or to wait until one arrives. Putting a customer into the queue just requires calling put(Customer).

I've ignored the business about colours because it makes a difference whether the customer can have items of multiple colours or not, and what should happen if the answer is yes.
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Jeff Verdegan wrote:
Justin Thomas wrote:
2. wait() also implies there will be somewhere notify()


Of course. The thread that completes the conditions that you mentioned would call notify().




But... there is no notify in the example above.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Paul Clapham wrote:So each cashier is a queue. A BlockingQueue might be okay. When the cashier needs to serve the next customer, it calls take() on the queue to get one, or to wait until one arrives. Putting a customer into the queue just requires calling put(Customer).


Quite simple indeed. And a much clearer statement of requirements than the initial "Don't execute if something is in a Set" or the followup, "... but stop and wait until it's not."

@Justin: Please do NOT respond with anything even remotely like, "But I can't because the method is static." It almost certainly doesn't matter, and if it does, then your design is broken and you need to make it non-static. That part is not relevant to understanding the general problem of having a thread wait until some condition is met.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
Jeff Verdegan wrote:
Justin Thomas wrote:
2. wait() also implies there will be somewhere notify()


Of course. The thread that completes the conditions that you mentioned would call notify().




But... there is no notify in the example above.


Oops! My bad!


Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
I'll go with wait + notify. I'll code it tomorrow and then click "Resolved" (11:29pm now). Thank you for all your help.

and ps: being able to phrase a question really well gives instant google result, so no threads nowhere are made. So don't rage about it being unprecise.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18675
    
    8

Jeff Verdegan wrote:Quite simple indeed.


Yes. Those classes and interfaces in java.util.concurrent are quite simple, and they beat the pants off trying to write low-level code with wait() and notify(). In fact I would recommend that programmers use those classes for real-life programming and just ignore the low-level things. Concurrency is hard and it's easy to get it wrong, so the makers of java.util.concurrent put a lot of effort into building prefabricated tools which really work and which avoid all of the ugly gotchas which infest concurrency.

Frankly, the only reason I can see to learn how to use wait() and notify() is if you need to pass the certification exams which ask questions about them. Otherwise, if you've got real work to do, java.util.concurrent is the way to go.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Justin Thomas wrote:Rephrasing again (for simplicity reasons):

1. You are at supermarket. And there are clients and cashiers. (You are client)
2. If you buy a green product you go to a green cashier. If you buy blue you go to blue one
3. One cashier can be handling only 1 customer at a time
4. Number of colors is unknown from beforehand
5. You (an object) can't move, the supermarket itself (static) moves you to a correct queue if you rise your hand.

I really don't know how to rephrase it any simpler :( :( :( :(


Well, I think as a first pass, the colors should be separated. There is no reason for one lock to handle all the colors, as cashiers will only handle one color. Think of it as having separate locks (for separate queues).

Next, I am not a fan of using notifyAll(), when a cashier finishes with one client, she can only handle another client, and hence, only one client needs to be woken. Of course, the edge conditions needs to be handled -- if a cashier don't have a client, it will wait. If a client sees a cashier in a wait state, it will go directly to the cashier, etc.

Henry
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:I'll go with wait + notify. I'll code it tomorrow and then click "Resolved" (11:29pm now). Thank you for all your help.


You're welcome.

and ps: being able to phrase a question really well gives instant google result, so no threads nowhere are made.


No, there are plenty of times when someone phrases a question clearly, but what's readily available by a search isn't presented in a way the person understands, or leaves out some details.

So don't rage about it being unprecise.


I'm not raging. I'm merely telling you that I found your question unclear and therefore could not answer it. What would you have me do? Pretend I know and give an answer to some other arbitrary question? Say nothing at all? I didn't point out the lack of clarity to criticize you. I did it to move the discussion along to a place where I could help you.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Next, I am not a fan of using notifyAll(), when a cashier finishes with one client, she can only handle another client, and hence, only one client needs to be woken.


If there can be multiple threads waiting, then even though only one can proceed, I prefer notifyAll() unless there's evidence that the number of threads is so large and the wait/notify cycle time so short that notifyAll() leads to unacceptable overhead.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Paul Clapham wrote:
Yes. Those classes and interfaces in java.util.concurrent are quite simple, and they beat the pants off trying to write low-level code with wait() and notify(). In fact I would recommend that programmers use those classes for real-life programming and just ignore the low-level things. Concurrency is hard and it's easy to get it wrong, so the makers of java.util.concurrent put a lot of effort into building prefabricated tools which really work and which avoid all of the ugly gotchas which infest concurrency.

Frankly, the only reason I can see to learn how to use wait() and notify() is if you need to pass the certification exams which ask questions about them. Otherwise, if you've got real work to do, java.util.concurrent is the way to go.


A few reasons to choose the concurrent packages Lock and Condition classes over synchronization and wait() and notify(). It can grant locks in an order manner -- so going back to the supermarket example, it means that clients can't skip the line (well they can, but it's more fair). You can have more than one condition variable per lock. So, if you do want to have one lock for the supermarket, and have different condition variables to represent the different queues, that can be done too.

Henry

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Paul Clapham wrote:
Yes. Those classes and interfaces in java.util.concurrent are quite simple, and they beat the pants off trying to write low-level code with wait() and notify(). In fact I would recommend that programmers use those classes for real-life programming and just ignore the low-level things. Concurrency is hard and it's easy to get it wrong, so the makers of java.util.concurrent put a lot of effort into building prefabricated tools which really work and which avoid all of the ugly gotchas which infest concurrency.

Frankly, the only reason I can see to learn how to use wait() and notify() is if you need to pass the certification exams which ask questions about them. Otherwise, if you've got real work to do, java.util.concurrent is the way to go.


A few reasons to choose the concurrent packages Lock and Condition classes over synchronization and wait() and notify(). It can grant locks in an order manner -- so going back to the supermarket example, it means that clients can't skip the line (well they can, but it's more fair). You can have more than one condition variable per lock. So, if you do want to have one lock for the supermarket, and have different condition variables to represent the different queues, that can be done too.

Henry



For most real production code, I generally prefer the j.u.c classes as well. However, I still think it's worth learning the lower level concepts. And there are times when I find it easier to just throw in a quick sync/wait/notify rather than messing around with the j.u.c objects. (Especially just a plain sync vs. a Lock.)
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Justin Thomas wrote:I'll go with wait + notify. I'll code it tomorrow and then click "Resolved" (11:29pm now). Thank you for all your help.


wait and notify methods are not static.
I told you static plays a role here but you just ignored it. I can't call wait() or notify() because they are non static.

I'm going to look for other solution then. Maybe that BlockingQueue...

I did this:


Yet my Netbeans says I am using wait and notify outside of synchronized block. I tried adding the block, but at: http://tutorials.jenkov.com/java-concurrency/synchronized.html it's written that "Only one thread can execute inside a code block synchronized on the same monitor object." and since the method is static (see, again it is important that it is static) I decided not to use synchronized block at all, however it probably makes the code not correct. I also noticed that if at least ONE execution gets locked then the function will never exit and give a chance for the code to continue. So the wait() notify() is wrong for 2 reasons then....


-------
Edit 2: I thought of this:


I thought of 2 dangers:
1. Values are parsed to function as reference, so will there be lock based on String contents or on the reference itself?
2. If it get's locked, it would be good to spawn each function in separate thread.


--
edit 3
When I implement runnable I only get command run() so passing all 3 parameters seems impossible. Maybe a workaround? I'll think of it....


---
edit 4: I figured workaround for passing all arguments


So that makes it a good working solution, except for the fact that I am unsure whether the synchronize(string_here) synchronizes on string's value or on a pointer/reference. I will click "Resolved" nevertheless.

As far as synchronizing upon String, I found: http://www.javalobby.org/java/forums/t96352.html and http://javarevisited.blogspot.com/2011/04/synchronization-in-java-synchronized.html but it is still unclear to me whether I can synchronize on that string.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Justin Thomas wrote:
wait and notify methods are not static.
I told you static plays a role here but you just ignored it. I can't call wait() or notify() because they are non static.

I'm going to look for other solution then. Maybe that BlockingQueue...

I did this:




Synchronized static methods use instance of class Class as it's synchronized lock, so if you want to do a wait and notify with the same lock, one option is to lock on the class variable -- meaning synchronize the method, and use the instance of the class Class.

In your example, you chose a different (and perfectly acceptable) option, but you seemed to have forgotten synchronized on it. One of the requirements of wait and notify, is that you must own the synchronization lock for the object that you want to send notifications with.

Justin Thomas wrote:
Yet my Netbeans says I am using wait and notify outside of synchronized block. I tried adding the block, but at: http://tutorials.jenkov.com/java-concurrency/synchronized.html it's written that "Only one thread can execute inside a code block synchronized on the same monitor object." and since the method is static (see, again it is important that it is static) I decided not to use synchronized block at all, however it probably makes the code not correct. I also noticed that if at least ONE execution gets locked then the function will never exit and give a chance for the code to continue. So the wait() notify() is wrong for 2 reasons then....


It is actually a little more complicated than that -- you need the synchronization, or the shared variables (the static variables, if they change) will have race conditions. You need to synchronize the methods so that those variables are protected. In order to help you, the wait() method does release the lock (and do so atomically, as to not lose notifications), so you need to make sure that none of your variables are in an interim state prior to the wait(), and not assume the state after the wait().

Henry

Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Justin Thomas wrote:
Edit 2: I thought of this:


I thought of 2 dangers:
1. Values are parsed to function as reference, so will there be lock based on String contents or on the reference itself?
2. If it get's locked, it would be good to spawn each function in separate thread.


Synchronization are on the object (not the reference). This means that .... (1) two threads using different references to the same instance will synchronize with each other, and (2) two threads using the same reference, but that reference is changing, may *not* synchronize with each other.

Not sure what you mean by "spawn each function in separate thread". Every thread has it's own call stack, so every method call will guarantee that local variables (which parameters references are) will not be shared.

Justin Thomas wrote:
edit 3
When I implement runnable I only get command run() so passing all 3 parameters seems impossible. Maybe a workaround? I'll think of it....


Not completely sure what you mean by this... can you elaborate the issue? .... [EDIT] oh I see what you mean (in your next edit). Never mind.

Henry
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Umm there is one more issue: the synchronization seems not to work at all:



And I got 2 same* uuid challanges passed in a row one by one. Just in case the execute was being performed super fast (in case of error), I used ps aux to monitor the processes - everything in earth and heaven points to the fact that synchronization block is not working. Now I am... surprised.

There were 2 threads, each initiating ProcessCommon.executeOne(commands, dir, hdd_id); //ProcessCommon <- name of class
So 1 should go through immidiately and the other should wait (around) 30 sec for first to finish :(

*Yes I checked if they were the same. Check yourself:
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Justin Thomas wrote:Umm there is one more issue: the synchronization seems not to work at all:



And I got 2 same* uuid challanges passed in a row one by one. Just in case the execute was being performed super fast (in case of error), I used ps aux to monitor the processes - everything in earth and heaven points to the fact that synchronization block is not working. Now I am... surprised.

There were 2 threads, each initiating ProcessCommon.executeOne(commands, dir, hdd_id); //ProcessCommon <- name of class
So 1 should go through immidiately and the other should wait (around) 30 sec for first to finish :(

*Yes I checked if they were the same. Check yourself:
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f



This check isn't sufficient -- it is possible to have two different strings holding the same value.

Another possible check (which is also isn't sufficient, but better) is to use the identity hashcode. Use the System class to get the strings identity hashcode.

Henry
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Henry Wong wrote:
This check isn't sufficient -- it is possible to have two different strings holding the same value.

Another possible check (which is also isn't sufficient, but better) is to use the identity hashcode. Use the System class to get the strings identity hashcode.

Henry


I added: System.out.println("Hashcode for above: " + HardDrive_UUID.hashCode());

Output:
Hashcode for above: -774026551
Hashcode for above: -774026551

:( :(

So... what now ?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Justin Thomas wrote:
Henry Wong wrote:
This check isn't sufficient -- it is possible to have two different strings holding the same value.

Another possible check (which is also isn't sufficient, but better) is to use the identity hashcode. Use the System class to get the strings identity hashcode.

Henry


I added: System.out.println("Hashcode for above: " + HardDrive_UUID.hashCode());

Output:
Hashcode for above: -774026551
Hashcode for above: -774026551

:( :(

So... what now ?



Not the hashcode. The *identity* hashcode. You can get it from the java.lang.System class.

Henry
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Thomas wrote:
Justin Thomas wrote:I'll go with wait + notify. I'll code it tomorrow and then click "Resolved" (11:29pm now). Thank you for all your help.


wait and notify methods are not static.


I know. Never said or even remotely implied otherwise.

I told you static plays a role here but you just ignored it. I can't call wait() or notify() because they are non static.


I didn't ignore it. I correctly told you it doesn't matter that your method is static. Whenever you are in a synchronized block or method, you have obtained an object's lock. It is that object on which you need to call wait() or notify(). If you are in a non-static synchronized method, that object is "this". If you are in a static synchronized method, that object is the Class object for the current class.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Justin Thomas wrote:
*Yes I checked if they were the same. Check yourself:
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f



This check isn't sufficient -- it is possible to have two different strings holding the same value.


But these aren't just Strings. They're UUIDs, which, by definition are unique (with high enough probability that we can just say "they are"). So if he's getting the same value twice, then at least one of the following is true. (Note that I haven't been keeping up in enough detail to know at what step in the process we're seeing the repeats.)

1) His random UUID generator is faulty.

2) His code to lock out the processing of a given UUID to "once only" or "one at a time" is faulty.

3) That UUID legitimately showed up for processing twice (which means he needs something other than UUID to identify an item).

Another possible check (which is also isn't sufficient, but better) is to use the identity hashcode. Use the System class to get the strings identity hashcode.


I disagree. If a UUID isn't providing the required uniqueness, he needs to either fix that or use something else, like a generated sequence number, or reference equality. (Again, these are just high level ideas, since I'm not intimately familiar with the requirements or how the current attempted solution is failing to meet them.)
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18896
    
  40

Jeff Verdegan wrote:
Henry Wong wrote:
Justin Thomas wrote:
*Yes I checked if they were the same. Check yourself:
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f



This check isn't sufficient -- it is possible to have two different strings holding the same value.


But these aren't just Strings. They're UUIDs, which, by definition are unique (with high enough probability that we can just say "they are"). So if he's getting the same value twice, then at least one of the following is true. (Note that I haven't been keeping up in enough detail to know at what step in the process we're seeing the repeats.)


Based on the code, Justin is using strings. And he is also synchronizing on them -- or do you mean that his generator is not making sure that there is only one copy of each ID string?

Henry
Justin Thomas
Ranch Hand

Joined: Mar 08, 2012
Posts: 62
Henry Wong wrote:
Not the hashcode. The *identity* hashcode. You can get it from the java.lang.System class.

Henry


Did the correct one this time.
Hashcode for above: 219987657
Hashcode for above: 1942571857

But it was said previously in this thread that the lock is based on value not on reference - and the value is the same. Why doesn't it work... ffs.

Object 1 in Thread 1:
Gathers data
Gathers also UUID string
Sends data + uuid to that static method above

Object 2 in Thread 2:
Gather data
Gathers also UUID
Sends data + uuid to that static method above

And those uuids are the same!!! I wasted in total 8 hours trying to make a simple conditional synchronization.... come on.... why it the hell doesn't work!!!

And I haven't even STARTED writing test cases where there are more than 2 thread and more than 1 uuid......


---
and for all those who wonder uuid is generated this way:
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Henry Wong wrote:
Jeff Verdegan wrote:
Henry Wong wrote:
Justin Thomas wrote:
*Yes I checked if they were the same. Check yourself:
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f
Performing UUID challange with: unrar58a3e6ef-8fa6-4df7-8650-a5ee57b1b64f



This check isn't sufficient -- it is possible to have two different strings holding the same value.


But these aren't just Strings. They're UUIDs, which, by definition are unique (with high enough probability that we can just say "they are"). So if he's getting the same value twice, then at least one of the following is true. (Note that I haven't been keeping up in enough detail to know at what step in the process we're seeing the repeats.)


Based on the code, Justin is using strings. And he is also synchronizing on them -- or do you mean that his generator is not making sure that there is only one copy of each ID string?

Henry


Sorry, I should have been more precise.

Based on the format of those strings and on his variable names, they appear to be String representations of UUIDs. In terms of my ensuing comments, the rest of it still stands: Either the thing producing the IDs is erroneously producing duplicates, or else the duplicates are valid in and of themselves because the ID of the same "identified thing" is being presented twice.

If the latter, then either it's being presented twice because it's supposed to be, and he's misdiagnosing correct duplicates as incorrect, or else there's a bug in either the identification of the things to process or in the handling of the mutex for that processing.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to block access based on elements existance?