I've been writing a program to help me at my job recently, sort of as a project to show our IT department the kind of software that I need for my position, I 'spose. Well, one of the things I've been concerning myself with this set of applications and class objects is concurrency, since many of the apps used in RTVHelper (the current working name) are, in fact, multi-threaded. One of the utilities I'm developing for this set of software is something I'm calling the "ReentrantReadWriteCollectionsWrapper", an unnecessarily long-named object that wraps around objects that implement the Collections interface and provide for it thread-safety through Reentrant locks using the java.util.concurrent.ReentrantReadWriteLock object. Anyway, when dealing with these locks, it's possible that while a thread is awaiting a lock from the ReentrantReadWriteLock, that it will be interrupted. If this happens, the object will throw an InterruptedException, and this is the crux of my problem.
Since I have to implement the Collection interface for this object (as it is supposed to be a wrapper), none of the methods can be flagged to throw InterruptedException as that is not part of the object's expected interface. If I accept that and make the interface of this wrapper incompatible with the Collection interface, then this object will not be able to take advantage of methods coded to the Collection interface. I can also throw a RuntimeException, which doesn't necessarily break the interface, but it does introduce the sudden possibility that every method in the object can throw a RuntimeException, which, depending on where in the execution Thread 1 is in the middle of using the ReentrantReadWriteCollectionsWrapper, when Thread 2 interrupts Thread 1, the Collection being executed with Thread 1 WILL throw that RuntimeException and if there's no handler will forcibly close the Java App. Simply put, I'd much rather not use a RuntimeException. I could silently ignore the InterruptedException and set a flag in the object, but then the program relies on the client checking this flag, and what's more, methods working on Collections won't look for this flag so if the interruption occurs rather early in the method, there's a lot to ignore, and no way to tell just how far into the method it was done before the interruption occurred. Finally, I also attempt to come up with some kind of static behavior to handle InterruptionException, but this leaves the client of the Wrapper no alternatives or options.
I just wanted to see if you guys had any good ideas for what to do with this? Maybe there's something I hadn't considered yet.
Dealing with Checked Exceptions behind an Interface Not Suited for it.
Started by ZekeDragon, Apr 21 2011 11:43 AM
4 replies to this topic
#1
Posted 21 April 2011 - 11:43 AM
Wow I changed my sig!
|
|
|
#2
Posted 21 April 2011 - 10:58 PM
So, let me get this straight (I always used Collections.synchronizedX() ) if i wanted a thread safe collection.
Now, the biggest reason you're stuck is at one side, the interface, at the other side. The fact that you would like to use your class with java-defined methods who work with this interface, and thus also your class.
What I would do is, drop the last, and implement your own methods for those java defined methods, where you internally use the java-defined method, but catch a RuntimeException and convert this one to an InteruptedException.
Perhaps a short example makes it more clear what I mean. Basicly, you gonna wrap your wrapper class :P
- But if I understand it correctly, the more threads you have that are going to read or write, the more interesting the ReentrantReadWriteLock may become.
- You want to let your own class implement Collection interface so that it's possible to do:
private ReentrantReadWriteCollectionsWrapper rrwcw = new ReentrantReadWriteCollectionsWrapper(); ... (java.util.)Collections.max(rrwcw);
Now, the Collections class only has min(), max(), and unmodifiableCollection() which take a Collection as parameter, so I gues there are more methods of other classes...
- You're not acutally writing your own collection, but wrap another like so:
public class ReentrantReadWriteCollectionsWrapper implements Collection{ private Collection collection; private ReentrantReadWriteLock rwl; public ReentrantReadWriteCollectionsWrapper(Collection collection){ this.collection = collection; rwl = new ReentrantReadWriteLock(); } public void add(Object o){ rwl.writeLock().lock(); //Can now throw InterruptedException from here collection.add(o); rwl.writeLock().unlock(); //To here, but the method can't throw it due to interface } }
Now, the biggest reason you're stuck is at one side, the interface, at the other side. The fact that you would like to use your class with java-defined methods who work with this interface, and thus also your class.
What I would do is, drop the last, and implement your own methods for those java defined methods, where you internally use the java-defined method, but catch a RuntimeException and convert this one to an InteruptedException.
Perhaps a short example makes it more clear what I mean. Basicly, you gonna wrap your wrapper class :P
public class MyCollectionWrapper {
private [COLOR="#9acd32"][B]InnerCollection [/B][/COLOR]innerCollection;
public boolean isEmpty() throws InterruptedException{
try{
return innerCollection.isEmpty();
} catch (RuntimeException e){
throw new InterruptedException(e.getMessage());
}
}
public Object collectionsMax() throws InterruptedException{
try{
return Collections.max(innerCollection);
} catch (RuntimeException e){
throw new InterruptedException(e.getMessage());
}
}
[B][COLOR="#9acd32"]private class InnerCollection[/COLOR][/B] implements Collection {
public boolean isEmpty() {
throw new RuntimeException("!!!>>message<<!!!");
}
//other methods of Collection
}
public static void main(String[] args) throws InterruptedException {
MyCollectionWrapper wrap = new MyCollectionWrapper();
wrap.isEmpty();
}
}
#3
Posted 22 April 2011 - 10:12 AM
Hmm, unfortunately I don't think that this matches the requirements of my project. The Wrapper class is supposed to be used directly, but that's not the problem, instead the point of this collection is to be used to back relatively simple Model objects in a multithreaded environment. I figured it'd be much easier to Synchronize the data inside a model object and then leave the model mostly unsynchronized instead of coding synchronization into each of my models, which would be the conventional way to do it. I can't wrap the models since by a model object's very nature it's an interface to a particular type of view (look at classical MVC, I know you have a different idea with model-view interaction, but this project uses classical MVC), but it's underlying data structures can be. Thus, that's what I'm doing.
I was using the Collections.syncronizedBlah() methods before this, the only problem is that the threads don't work too well together with a multithreaded model object with simple synchronization. Since not just views will be being used to access the models, other threads could be attempting to read the Collection at the same time the view(s) are (which is managed pretty much entirely by the Event Dispatch Thread). A couple of the projects I intend on using this wrapper in could have a dozen or more threads reading from various Collections/Lists/Maps, performing comparisons, etc. all the time. If each of these objects is synchronized, it'd prohibitively slow down the program or cause the potential for far more locking up than I feel comfortable with. So I set out to develop what is essentially an improved thread-safe wrapper for Collections, Lists, and Maps for this project. I also actually intend on, when I feel close to done with it, posting the full source here to give everyone else a run at testing/learning from/insulting it.
I think that the Collections class has more than that, for example frequency(), enumeration(), and addAll(). There's also quite a few objects in my Java Utility Toolkit that work on Collections I'd like to be able to reuse. :)
I really do appreciate your suggestion, and it ended up giving me the idea of doing what I'm doing with this class. I decided to instead allow the user of the object to create another object for the ReentrantReadWriteCollectionsWrapper called an "InterruptHandler", which has a method called "handleIt()" that takes an InterruptedException and a String indicating the name of the method as arguments. The class will come out-of-the-box with a default implementation that throws an unchecked exception from the object (and calls a method called "rollback()", which is an entirely different feature of the ReentrantReadWriteCollectionsWrapper). This makes it so the Interrupts are handled implicitly but the user still has control to handle it themselves.
I was using the Collections.syncronizedBlah() methods before this, the only problem is that the threads don't work too well together with a multithreaded model object with simple synchronization. Since not just views will be being used to access the models, other threads could be attempting to read the Collection at the same time the view(s) are (which is managed pretty much entirely by the Event Dispatch Thread). A couple of the projects I intend on using this wrapper in could have a dozen or more threads reading from various Collections/Lists/Maps, performing comparisons, etc. all the time. If each of these objects is synchronized, it'd prohibitively slow down the program or cause the potential for far more locking up than I feel comfortable with. So I set out to develop what is essentially an improved thread-safe wrapper for Collections, Lists, and Maps for this project. I also actually intend on, when I feel close to done with it, posting the full source here to give everyone else a run at testing/learning from/insulting it.
wim DC said:
Now, the Collections class only has min(), max(), and unmodifiableCollection() which take a Collection as parameter, so I gues there are more methods of other classes...
I really do appreciate your suggestion, and it ended up giving me the idea of doing what I'm doing with this class. I decided to instead allow the user of the object to create another object for the ReentrantReadWriteCollectionsWrapper called an "InterruptHandler", which has a method called "handleIt()" that takes an InterruptedException and a String indicating the name of the method as arguments. The class will come out-of-the-box with a default implementation that throws an unchecked exception from the object (and calls a method called "rollback()", which is an entirely different feature of the ReentrantReadWriteCollectionsWrapper). This makes it so the Interrupts are handled implicitly but the user still has control to handle it themselves.
Wow I changed my sig!
#4
Posted 22 April 2011 - 11:11 AM
Quote
I think that the Collections class has more than that, for example frequency(), enumeration(), and addAll(). There's also quite a few objects in my Java Utility Toolkit that work on Collections I'd like to be able to reuse.
#5
Posted 22 April 2011 - 03:50 PM
I downloaded the SE 6 docs since my laptop is frequently out of range of a wireless at my job, and I still like to have access to those. :)
Wow I changed my sig!
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account

Back to top










