We use ConcurrentLinkedHashMap from https://code.google.com/p/concurrentlinkedhashmap/ in a project and I saw a note that it was integrated into Guava's MapMaker and CacheBuilder back in 2010. The info is very brief:
Integration of the algorithmic techniques into MapMaker will be released in Google Guava r08 and is heavily based on this version.
What does it mean exactly?
The concurrentlinkedhashmap project seems to be still active.
Was it just a one time integration to bootstrap the Guava cache package?
Have the two projects evolved independently since 2010?
If so, what are the main differences between them today?
What does it mean exactly?
Guava is the long term replacement and most of the time you should use it. The history is that ConcurrentLinkedHashMap figured out the algorithms, Guava subsumed it, and then focused on adding features.
The concurrentlinkedhashmap project seems to be still active.
It has always been a weekend project, so active means that I have a scratch to itch or responded to a change request. It is also easier to experiment in CLHM than Guava, so I tended to prove out ideas there prior us porting them over. My involvement with Guava was as a 20%-er.
Was it just a one time integration to bootstrap the Guava cache package?
Yes. We first overhauled MapMaker and then split out caching into a dedicated API. It is a one-way migration of ideas and improvements into Guava.
Have the two projects evolved independently since 2010?
Both have stayed dedicated to their goals. The motivation behind ConcurrentLinkedHashMap was to figure out how to write a truly concurrent cache without taking shortcuts. The goal behind Guava is to provide a feature rich library with a beautiful API and solid implementation for broad usage.
What are the main differences between them today?
Guava is packed with features and has a full time team at Google supporting it. Use it!
ConcurrentLinkedHashMap has higher absolute concurrency by decorating, instead of forking, ConcurrentHashMap. This allows it to be used with ConcurrentHashMapV8, which is based on a new algorithm. CLHM does not relying on segment locks, which improves write performance and allows for maintaining a single LRU chain. I have an experimental branch with the LIRS policy that I hope to someday finish.
The long term hope is that Doug Lea will one day write a cache inspired by our work and teach us a few things in the process.
Update (3/15): Caffeine is a Java 8 rewrite of Guava's cache. It tries to provide the best of ConcurrentLinkedHashMap and Guava, modernized with Java 8, and adopting the techniques that I've learned since those previous projects.
Related
In a critical part of my project which basically allows objects to be received by a controller asynchronously, put into a Queue, processed sequentially from the queue one at a time by a thread, then service responds, older processed objects are kept in the queue until newer item insertion.
Back in time (months ago), my Queue implementation for solving this particular business specific issue behind this was to use Guava's EvictingQueue, which now is marked as #Beta, and so this part of the application can break in future Guava releases.
private final Queue<SomeRandomBusinessObject> items = Queues.synchronizedQueue(EvictingQueue.create(queueSize));
Are there any thread-safe and fixed-size alternatives to EvictingQueue to achieve this goal?
There are couple of inaccuracies / mistakes in your post, so let's just try to find common ground.
First, any new feature in Guava is annotated as #Beta from the beginning, same is true for EvictingQueue in 15.0 (this links to 15.0 docs). So you probably missed that fact couple months ago, but that's OK, because...
...#Beta doesn't really mean it'll be changed without any notice -- on the contrary, some time ago, after some feedback from the community, Guava devs established pretty strict policy about what and when can be changed. See PhilosophyExplained wiki page, which says (emphasis mine):
Beta APIs
Beta APIs represent Guava features that we aren't ready to freeze for whatever reason: because the methods might not find enough users, because they might be moved, because their uses might be too narrow to include them in Guava.
That said, #Beta APIs are fully tested and supported, and treated with all the care and affection that the rest of Guava receives.
This means EvictingQueue quality is not worse than if it wasn't a "beta feature".
The biggest connotation of the #Beta annotation is that annotated classes or methods are subject to change. They can be modified in any way, or even removed, at any time. If your code is a library itself (i.e. it is used on the CLASSPATH of users outside your own control), you should not use beta APIs, unless you repackage them (e.g. using ProGuard).
This could be the concern you brought up when talking about "braking up in the future", but...
All this said, #Beta features tend to remain relatively stable. If we decide to delete a #Beta feature, we will typically deprecate it for one release before deleting it.
So it won't happen silently (as far as I observed, usually there's more than one release with deprecating though).
Which brings me the the last point:
On the other hand, if you want something taken out of #Beta, file an issue. We generally promote features out of #Beta only when it's specifically requested, so if you don't ask, it won't happen.
To sum up: I'd suggest you to file a ticket to promote EvictingQueue and make it non-#Beta, which would remove any doubts about it. On the other hand, the EvictingQueue's implementation is quite simple and standalone, so if it's removed (unlikely) you can repakckage it (i.e. use ProGuard) or even copy the code to your project (with all the licenses).
MapMaker maximumSize in google guava library is marked as #Beta. It's a very useful feature to set the maximum size when you use it as a cache and I would like to use it in production code. From experience with other google products beta can be pretty solid. Anyone know why it's a #Beta?
It is used in production at Google and there are no immediate plans on API changes. There is consensus to support weighted entries and we'll likely continue to evolve the algorithm to be closer to ConcurrentLinkedHashMap's. In this case #Beta is just to indicate that the method contract isn't officially set in stone.
From the javadoc:
Signifies that a public API (public class, method or field) is subject to incompatible changes, or even removal, in a future release. An API bearing this annotation is exempt from any compatibility guarantees made by its containing library.
So it doesn't mean it's questionable quality, or unsuitable for production use, they just reserve the right to change it later.
If your project is an end application that is not intended to be embedded in other peoples' applications, then anything with #Beta is totally safe to use. The API may change later and IMO the greatest risk you run is that you might have to change your code a little bit because a method signature changed.
If, on the other hand, you are developing some sort of framework where you expect your project will be on the classpath of many clients, you probably want to avoid #Beta. You never know if your clients will have a different version of Guava on the classpath -- in which case unpredictable things can happen.
ColinD explains this best here: Best Way To Use Guava
edit: Ah yes, and to answer your specific question of why call it #Beta -- it's just to document this fact that MapMaker maximumsize is still subject to change in the next release (It's not that the code is thought to be flaky, unstable, or unsuitable for production)
It seems like every java project I join or start on always has commons-lang as a dependency - and for good reason. commons-lang has tons of classes and utility methods that are pretty standard fair with the most standard APIs in other languages. Why hasn't Sun/Oracle/JCP adopted some of the things in commons-lang in to the standard api?
As pointed out already, some features in the commons API have made it into Java, often implemented (IMHO) better than they were originally in the commons library. Enums is the classic example.
In terms of why they don't adopt more of commons-lang, well with some classes there's the element of confusion. Take StrBuilder for example, it's more powerful than the Java StringBuilder and it's extensible. But I'm not sure I'd be for adding such a class into the Java core API, StringBuilder/StringBuffer are perfectly good enough for most purposes and having another one in there would really just become a bit confusing. They couldn't really alter StringBuilder in a way that would accommodate all of the changes either because that could break existing code. Even if they did add one, what about when someone else came along with another more powerful version? StrBuilder2? Before long everything's a big mess (some argue that the core API is already, let alone with such additions.)
And as always with these things, the big point is what should be included from commons-lang. Some people would probably want to see the MutableXXX classes added, others the XXXUtils classes, others the time package... there isn't really a common consensus.
The other big thing is that the Java developers have to be a lot more careful what goes in the core Java API than the Apache developers do for commons-lang. If a crappy design in commons-lang is superseded in a future release, the old one can be deprecated and subsequently removed (indeed this seems to be what happens.) In the core Java API it needs to stay for backwards compatibility reasons, just causing more clutter.
For what it's worth though I do think more of the functionality in commons-lang should probably be included. I can just see the reasons, at least in part, why it's not.
Historically Apache Commons implemented some of the features that later were introduced in Java 5, such as enums and annotations. Their implementation was sufficiently different to make integration difficult.
One chapter in Pragmatic Programmer recommends looking at a blackboard/space-based architecture + a rules engine as a more flexible alternative to a traditional workflow system.
The project I'm working on currently uses a workflow engine, but I'd like to evaluate alternatives. I really feel like a SBA would be a better solution to our business problems, but I'm worried about a total lack of community support/user base/venders/options.
JavaSpaces is dead, and the JINI spin-off Apache River seems to be on life support. SemiSpace looks perfect, but it's a one-man show. The only viable solution seems to be GigaSpaces.
I'd like to hear your thoughts on space based architecture and any experiences you've had with real world implementations.
Why do you regard Javaspaces as dead, beyond the fact that the Jini 2.1 release was some time ago (October 2005) ? Having used that, I'd suggest that it indicates a mature and complete technology set rather than something abandoned and defunct.
For another implementation of Javaspaces, take a look at Blitz Javaspaces. That's maintained and enhanced more regularly (latest release July 2008) and offers a more performant and manageable Javaspace implementation than the default outrigger supplied by Sun.
Gigaspaces is a successful commercial implementation of JavaSpaces -- so, I wouldn't say JavaSpaces is dead.
You might take a look at Java Shared Data Toolkit (also this article) to see if it meets your requirements.
Space-based architecture is a distributed-computing architecture for achieving linear scalability of stateful, high-performance applications using the tuple space paradigm With a space-based architecture, applications are built out of a set of self-sufficient units, known as processing-units.
Ex: Gigaspaces
here I attached the reference for gigaspaces.
https://docs.gigaspaces.com/latest/overview/space-based-architecture.html
While it doesn't support the JavaSpaces API, I'd suggest looking at Oracle Coherence for a distributed and reliable "live" data store that can drive event-based workflow. Deutsche Bank, for example, successfully replaced a "SBA" (Space Based Architecture) with an event-driven system built on Coherence for their FX trading, because of both reliability and performance issues.
For the sake of full disclosure, I work at Oracle. The opinions and views expressed in this post are my own, and do not necessarily reflect the opinions or views of my employer.
I'm astonished that the Apache Commons Collections project still hasn't got around to making their library generics-aware. I really like the features provided by this library, but the lack of support for generics is a big turn-off. There is a Lavalabs fork of Commons Collections which does support generics, which seems to claim backward compatibility, but when I tried updating to this version, my web application failed to start (in JBoss).
My questions are:
Whether anyone has successfully updated from Commons Collections to the fork mentioned above
If Commons Collections has any plans to add support for generics
BTW, I'm aware of Google collections, but am reluctant to use it until the API stabilises.
Cheers,
Don
Consider Google Collections. From their Javalobby interview:
[Google Collections is] built with Java 5 features: generics, enums, covariant return types, etc. When writing Java 5 code, you want a collections library that takes full advantage of the language. In addition, we put enormous effort into making the library complete, robust, and consistent with the JDK collection classes.
There are contributions. Checkout the jira's
There is also a JDK5 branch.
We do would like to add generics and update Commons Collections to 1.5 (and 1.6). The biggest problem is how to address backwards compatibility. And people have very different opinions there. For some of the Commons components the newer JDK almost asks for a rewrite for the new JDKs IMHO.
During ApacheCon I felt the urge across several people to get this moving though. It's just a big task.
Feel free to show up on dev#commons.apache.org
cheers,
Torsten
Given that the last word in Jakarta's own internal debate was in Dec 07, I would say that Apache will not embrace generics, leaving the field open for something Java5 friendly like Google Collections.
I say, bite the bullet and switch to google-collections, at least for new code.
I know you're concerned about stability, but the google-collections library is VERY close to stable for 1.0 release -- hang out on the dev list or watch their reported issues, they are already very very cautious about changes, especially breaking ones. Any incompatibilities between the current release and the (seemingly imminent) 1.0 final are going to be extremely tiny.
Also, if you're worried about stability, pick a version (e.g. the current one, 1.0 RC4), and... just don't upgrade. Sure, you won't get any new features, but commons-collections hasn't been updated in a meaningful way in several years, so are you really any worse off? At least you're frozen on something with generics and (IMHO) a much better API.
The general BC problem is that package org.apache.commons.collections has been renamed to org.apache.commons.collections15. I don't know the reason of this change. Try to rename it back, recompile the library and run your application again.
I have found this issue using Clirr tool on commons-collections-3.2.1.jar (from Apache) and collections-generic-4.01.jar (from Lavalabs).
I can't imagine what reason you can have to don't use google collections. It's quite simple to use that library.
For my work i use both, apache collections and google collections.
can you explain more about why you can't use google collections?
regards
There's a genericised port of Commons Collections 3.1 available here, which we've been using for a few years now. Does the job nicely, and since it's based strictly on the existing Commons source, it has a stable API.
It could use updating to conform to Commons Collections 3.2, though.
Have a read on the collection blog, it provide the completed understanding of the collection framework.
http://tech.konnectingtheworld.com/2010/09/a-note-on-java-collections/
If you feel that you query has not been answered, get in touch with me. I shall try to provide you the information as much as I can.