javamultithreadingproject-loom

Does a virtual thread wake up in the same carrier thread on which it was blocked?


Is my understanding correct that a virtual thread runs on the same carrier thread throughout its lifetime? If not, then I'm wondering if we'd need to have our instance variables as volatile to have the correct value after a virtual threads blocks in one carrier thread and wakes up in another. For example, see the code snippet below:

public class VirtualThreadDemo {

    private int disabledUserCount;

    void countDisabledUsers() {

        while (moreUsers()) {
            User user = getNextUserFromDb(); // virtual thread blocks for IO
            if (user.isDisabled())
                disabledUserCount++; // always happens in same carrier thread?
        }
        System.out.println(disabledUserCount);
    }
}

We don't have to declare disabledUserCount as volatile (because the carrier thread is gauranteed to remain same). Correct?

If not, what if it were a local variable?


Solution

  • Your understanding is wrong. Quoting JEP 425,

    A virtual thread can be scheduled on different carriers over the course of its lifetime

    However, it doesn't matter if a virtual thread gets scheduled on a new carrier. The Java Memory Model's guarantees are based on Java threads, not OS threads. Code running in a single virtual thread is running in a single thread as far as any synchronization requirements are concerned, regardless of how many carrier threads the virtual thread is scheduled on over its lifetime.

    You will not have to mark anything volatile with virtual threads that you would not have had to mark volatile with platform threads.