Q: Can a programmer determine whether a program's code will use green threads or native threads?
A: This means that you should write code that will run under green threads as well as it does under native threads. Native-thread code is relatively easy because it uses the operating system's thread-scheduling system, and most operating systems ensure that every thread gets a chance to run. High-priority threads run often, while low-priority threads rarely get their chance, but they all take turns.
Green threads, on the other hand, make no such guarantee. If a high-priority thread is running a loop of code that never
perform()s some blocking I/O function, then no other thread will ever execute. The only promise green threads make is that a high-priority thread will preempt a low-priority one. That means the burden of scheduling is on the programmer's shoulders. Code that takes responsibility for its own scheduling, though, will function well under both green and native threads -- and, as a bonus, should work well under the native threads of every operating system.
Taking responsibility for thread scheduling sounds difficult, but in practice most programs don't need to do much. Anytime a thread performs disk or network I/O, for instance, it gives other threads a chance to run.
Scheduling is more of a worry for programs with threads that run in tight loops or that spend significant amounts of time running mathematical computations with no I/O. In those cases, a simple call to
Thread.yield() is enough to give other threads of the same priority a chance to run. To share the CPU with a lower-priority thread, a thread can call
Thread.sleep() or, more precisely, call
wait() on an object until the low-priority thread signals the end of its run by calling
notify() on that object.