single thread executor

Miguel Ping miguel.ping at gmail.com
Mon Sep 7 10:57:14 UTC 2020


Thanks all,

I understand that by principle you won't want to do custom scheduling,
because virtual threads will be able to suspend at specified points and
free the carrier thread to be scheduled with another task.
I do like to understand the limits of loom by experimenting; eg: according
to the docs, getByName pin the carrier threads (at least right now), so if
by any reason my service is heavy on those calls I might want to schedule
that on dedicated threads.


-- Miguel


On Sun, Sep 6, 2020 at 11:28 AM Ron Pressler <ron.pressler at oracle.com>
wrote:

> > in a lot of cases you probably won't have to worry about carrier threads
> > since it is already set up for you.
>
> Exactly! A custom virtual thread scheduler is an advanced feature that
> should
> only be used in special circumstances.
>
> - Ron
>
>
>
> On 6 September 2020 at 09:15:29, Michael Bien (mbien42 at gmail.com(mailto:
> mbien42 at gmail.com)) wrote:
>
> > it might help to think of it being two layers. You have plain old java
> > threads which map to OS threads ("real" threads) and the new virtual
> > threads.
> >
> > Virtual threads can only make progress when they are mounted on carrier
> > threads, which are "real" threads. They add a nice feature however:
> > concurrent waiting (for resources) without blocking a carrier - which is
> > a big deal.
> >
> > to setup everything, carriers + virtuals:
> >
> > |// plain old thread factory and thread pool using the new builder
> > ThreadFactory carrierTF = Thread.builder().name("carrier#",
> > 0).factory(); ExecutorService carrierPool =
> > Executors.newFixedThreadPool( CARRIER_THREAD_COUNT, carrierTF);|
> >
> > |// factory for virtual threads scheduled on the carrier pool
> > ThreadFactory virtualTF = Thread.builder() .virtual(carrierPool)
> > .name("virtual#", 0).factory(); // thread executor will spawn a new
> > virtual thread for each task |||ExecutorService |executor =
> Executors.newThreadExecutor(virtualTF);|
> >
> >
> >
> > in a lot of cases you probably won't have to worry about carrier threads
> > since it is already set up for you.
> > for example this will schedule a new virtual thread on the default
> > scheduler, which is a ForkJoinPool.
> >
> > |Thread.startVirtualThread(() -> { System.out.println("Hello Loom from
> > "+Thread.currentThread()+"!"); });|
> >
> >
> > hope this helps a bit,
> >
> > michael
> >
> >
> > - - -
> > mbien.dev
> >
> > On 05.09.20 20:14, Miguel Ping wrote:
> > > Yeah I was about to reply exactly this.
> > >
> > > I always thought I knew basic executors, but now I find the api
> confusing:
> > > I create a ThreadExecutor that runs off a ThreadFactory (so far so
> good)
> > > that is built using virtual threads using a singleThreadExecutor.
> > > It's a bit confusing to see two executors here, but I guess the
> > > newThreadExecutor is just wrapping the threadFactory.
> > >
> > > Anyway, thanks alot for replying, especially on a saturday.
> > > I'm anxiously looking forward to continuing experimenting with Loom.
> > >
> > > Have a nice weekend.
> > >
> > > On Sat, Sep 5, 2020 at 6:02 PM Ron Pressler wrote:
> > >
> > >> Correction:
> > >>
> > >> It should be Executors.newThreadExecutor(tf) rather than
> > >> Executors.newUnboundedExecutor(tf).
> > >> The latter was the old API method, which has been renamed to the
> former.
> > >>
> > >> — Ron
> > >>
> > >>
> > >> On 4 September 2020 at 18:50:27, Ron Pressler (
> ron.pressler at oracle.com)
> > >> wrote:
> > >>
> > >> Remember, you want multiple virtual threads, but use only on platform
> > >> thread to schedule them. So you need to pass the single-thread
> executor
> > >> as the virtual thread scheduler:
> > >>
> > >> ThreadFactory tf =
> > >>
> Thread.builder().virtual(Executors.newSingleThreadExecutor()).factory();
> > >>
> > >> And then you can use the thread factory directly to create virtual
> > >> threads,
> > >> or use it like so:
> > >>
> > >> ExecutorService e = Executors.newUnboundedExecutor(tf);
> > >>
> > >> - Ron
> > >>
> > >>
> > >> On 4 September 2020 at 18:21:45, Miguel Ping (miguel.ping at gmail.com)
> > >> wrote:
> > >>
> > >> Hi all,
> > >>
> > >> I was experimenting with single thread executor and loom, and I was
> > >> expecting that if I have two tasks where the first call goes through
> > >> Socket.read, loom would schedule the second one. I'm pretty sure I'm
> doing
> > >> something wrong.
> > >>
> > >> Here's the output I got (I was expecting "Hello world" to appear
> before
> > >> "Connected!"; the program only concludes after I Ctrl+C the netcat
> > >> process):
> > >>
> > >>
> > >> $ nc -p 5555 -kl
> > >>
> > >> -- output --
> > >> sleeping 1s
> > >> Connected!
> > >> Hello world
> > >>
> > >> -- java --
> > >>
> > >> import java.net.InetSocketAddress;
> > >> import java.nio.ByteBuffer;
> > >> import java.nio.channels.SocketChannel;
> > >> import java.util.Arrays;
> > >> import java.util.concurrent.Callable;
> > >> import java.util.concurrent.Executors;
> > >>
> > >> public class Test {
> > >>
> > >> public static String block() {
> > >> // nc -p 5555 -kl
> > >> try {
> > >> System.out.println("sleeping 1s");
> > >> Thread.sleep(1000);
> > >> var socket = SocketChannel.open();
> > >> socket.connect(new InetSocketAddress("localhost", 5555));
> > >> System.out.println("Connected!");
> > >> socket.read(ByteBuffer.allocate(10)); // I was hoping this would
> allow the
> > >> other task to be scheduled
> > >> return "End";
> > >> } catch (Exception e) {
> > >> e.printStackTrace();
> > >> return "Failed";
> > >> }
> > >> }
> > >>
> > >> public static String print() {
> > >> System.out.println("Hello world");
> > >> return "Printed";
> > >> }
> > >>
> > >> public static void main(String[] args) throws Throwable {
> > >> var e = Executors.newFixedThreadPool(1,
> > >> Thread.builder().virtual().factory());
> > >> Callable t1 = Test::block;
> > >> Callable t2 = Test::print;
> > >>
> > >> var tasks = Arrays.asList(t1, t2);
> > >> var fut = e.invokeAll(tasks);
> > >> }
> > >> }
> > >>
> > >> --
> > >> Thanks
> > >>
> > >>
> >
>
>


More information about the loom-dev mailing list