tags:

views:

255

answers:

3

I would like to do some stuff in Java that would be clearer if written using concurrent routines, but for which full-on threads are serious overkill. The answer, of course, is the use of coroutines, but there doesn't appear to be any coroutine support in the standard Java libraries and a quick Google on it brings up tantalising hints here or there, but nothing substantial.

Here's what I've found so far:

  • JSIM has a coroutine class, but it looks pretty heavyweight and conflates, seemingly, with threads at points. The point of this is to reduce the complexity of full-on threading, not to add to it. Further I'm not sure that the class can be extracted from the library and used independently.
  • Xalan has a coroutine set class that does coroutine-like stuff, but again it's dubious if this can be meaningfully extracted from the overall library. It also looks like it's implemented as a tightly-controlled form of thread pool, not as actual coroutines.
  • There's a Google Code project which looks like what I'm after, but if anything it looks more heavyweight than using threads would be. I'm basically nervous of something that requires software to dynamically change the JVM bytecode at runtime to do its work. This looks like overkill and like something that will cause more problems than coroutines would solve. Further it looks like it doesn't implement the whole coroutine concept. By my glance-over it gives a yield feature that just returns to the invoker. Proper coroutines allow yields to transfer control to any known coroutine directly. Basically this library, heavyweight and scary as it is, only gives you support for iterators, not fully-general coroutines.
  • The promisingly-named Coroutine for Java fails because it's a platform-specific (obviously using JNI) solution.

And that's about all I've found.

I know about the native JVM support for coroutines in the Da Vinci Machine and I also know about the JNI continuations trick for doing this. These are not really good solutions for me, however, as I would not necessarily have control over which VM or platform my code would run on. (Indeed any bytecode manipulation system would suffer similar problems -- it would be best were this pure Java if possible. Runtime bytecode manipulation would restrict me from using this on Android, for example.)

So does anybody have any pointers? Is this even possible? If not, will it be possible in Java 7?


Edited to add:

Just to ensure that confusion is contained, this is a related question to my other one, but not the same. This one is looking for an existing implementation in a bid to avoid reinventing the wheel unnecessarily. The other one is a question relating to how one would go about implementing coroutines in Java should this question prove unanswerable. The intent is to keep different questions on different threads.


Further edited to add:

The answer is selected. Some commentary, however, is in order. The library pointed to is not a coroutine library, so it technically doesn't answer my question. That being said, however, it has two edges over the Google Code project linked to above:

  1. Both solutions use bytecode manipulation, but the selected library allows static bytecode manipulation which renders it usable in Android and other non-compliant JVM stacks.
  2. The Google Code project doesn't do full coroutines. While the answer's library doesn't even do coroutines at all, it does something more important: it provides a good, foundational tool for rolling my own full-featured coroutines.
+1  A: 

Your requirements seem to be:

  • lightweight - not based on Threads,
  • no reliance on native code, and
  • no use of bytecode modification.

I have a nasty feeling that these requirements have ruled out all sensible strategies for implementing coroutines in Java.

Stephen C
Yeah, that's my impression from my Googling. I was hoping there was things that people more expert in Java than I am could come up with that could do the job. Of your list there, the first two are non-negotiable because they basically eliminate all of the benefits of using coroutines (the first) or Java (the second). The third looks like it's the only remaining strategy possible which limits me to compliant JVM stacks. That's not that onerous a restriction, but a hassle for some situations (like Android). Thanks for the feedback so far. I'll leave this up for a bit before selecting.
JUST MY correct OPINION
Actually, there's a requirement you missed that makes the Google Code project linked up to above go down a notch in usability: proper coroutines, not mere generators. It should be possible to yield to any other coroutine, not just to the calling function. I know that you can make a dispatcher class that does that work for you, but that's an added hassle that's not necessary in a real coroutine library. I may wind up rolling my own stuff here anyway if nobody's done better.
JUST MY correct OPINION
+1  A: 

Javaflow is a continuation implementation, it will probably let you do that. It uses bytecode manipulation though.

Anyway, it feels like you're trying to do OOP with plain C. It's doable but it doesn't mean you should do it.

Guillaume
Yes, continuation libs will allow me to make full-featured coroutines on top. Thanks for the pointer.
JUST MY correct OPINION
OK, looking closer at this one, it uses bytecode manipulation but a key feature is that this bytecode manipulation can be done *statically*. This means that it could be used on non-compliant JVM stacks (like Android's) albeit with a performance hit. Nice catch. Thanks!
JUST MY correct OPINION
A: 

I checked the related question you linked and for the life of me I can't really understand what's so bad about threads. In Java threads never are native threads, they're merely isolated execution units which depending on context may be running as their own native thread if it's beneficial, that is splitting large execution blocks to own threads is smart while keeping small ones in just a few is more sensible due to the overhead.

That said, Java/JDK doesn't natively have coroutines available for high-level programmers - yet. JDK7 (whenever that comes out) will have what's known as jsr166y which is a Fork/Join framework by Doug Lea. For technical information, check this PDF by mr. Lea himself. In practice, Fork/Join adds another (useful!) level of granularity on top of Java's internal threading model which should help you achieve what you want.

Esko
Threads have serious overhead not just in execution but in programming related to locking and synchronization. Coroutines are just a better fit, as a result, to a wide variety of problems. They consume fewer processing resources and they consume far fewer mental resources in working out their interactions.
JUST MY correct OPINION
I just took a look at that jsr166y thing. It doesn't even come close to answering the problems that coroutines easily solve.
JUST MY correct OPINION