19 features • Learn an interesting concurrency model • Learn how to run code snippets with JBang • Learn how to write concise Java program with tricks that will make your coworkers mad
actor runtimes • Features of Java we will be using ☕ • Examples of actors (live coding) • An actor runtime (live coding) • A typed actor runtime (live coding) ☕ • An actor-based chat (live coding) • Virtual Threads and Project Loom • A Loom-based chat (live coding) Live coding with
in response to a message it receives, can concurrently: • send a finite number of messages to other actors; • create a finite number of new actors; • designate the behavior to be used for the next message it receives. "Everything" is an actor.
an actor • you invoke a method on an object • however in Smalltalk you send "messages" to objects • in fact, some people think that actors are "proper" OOP as envisioned by Alan Kay
◦ Mainstream statically typed OOP programming languages were verbose (C++/Java/C#) ◦ Dynamic languages were more concise Python/Ruby/Groovy • Enter Scala ◦ Static typing ◦ Dynamic feel / conciseness ◦ Actor library
{ var count = 10 def receive: Any => Unit = { case Ping => println(s"${self.path} received ping, count down $count") if (this.count > 0) { this.count = this.count - 1 sender() ! Ping } } } val system = ActorSystem("pingpong") val pinger = system.actorOf(Props[Pingponger](), "pinger") val ponger = system.actorOf(Props[Pingponger](), "ponger") pinger.tell(Ping, ponger)
Actor { def receive: Any => Unit = { case Ping(count) => println(s"${self.path} received ping, count down $count") if (count > 0) { sender() ! Ping(count - 1) } } } val system = ActorSystem("pingpong") val pinger = system.actorOf(Props[Pingponger](), "pinger") val ponger = system.actorOf(Props[Pingponger](), "ponger") pinger.tell(Ping(10), ponger)
Actor { def receive(msg: Any): Unit = msg match { case Ping(count) => println(s"${self.path} received ping, count down $count") if (count > 0) { sender() ! Ping(count - 1) } } } val system = ActorSystem("pingpong") val pinger = system.actorOf(Props[Pingponger](), "pinger") val ponger = system.actorOf(Props[Pingponger](), "ponger") pinger.tell(Ping(10), ponger)
{:ping, count, sender} -> IO.puts "#{name} received ping, count down #{count}" if count > 0 do send sender, {:ping, count - 1, self()} pingponger(name) else :ok end end end end pid1 = spawn fn -> Main.pingponger("pinger") end pid2 = spawn fn -> Main.pingponger("ponger") end send pid1, {:ping, 10, pid2}
if (message instanceof Auth a) { check(a.login()); if (validate(a.login(), a.token())) { // grant full access } else { // error } } else if (message instanceof Anon a) { // grant guest access } else unhandled(message); } pattern matching
actor runtimes • Features of Java we will be using ☕ • Examples of actors (live coding) • An actor runtime (live coding) • A typed actor runtime (live coding) ☕ • An actor-based chat (live coding) • Virtual Threads and Project Loom • A Loom-based chat (live coding) Live coding with
walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said “Master, I have heard that objects are a very good thing - is this true?” Qc Na looked pityingly at his student and replied…
his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.
Na, Anton attempted to impress his master by saying “Master, I have diligently studied the matter, and now understand that objects are truly a poor man’s closures.” Qc Na responded by hitting Anton with his stick, saying…
actor runtimes • Features of Java we will be using ☕ • Examples of actors (live coding) • An actor runtime (live coding) • A typed actor runtime (live coding) ☕ • An actor-based chat (live coding) • Virtual Threads and Project Loom • A Loom-based chat (live coding) Live coding with
JVMs "green" (user-mode) threads. • The green threads of the 90s still had large, monolithic stacks. • A product of their time ◦ systems were single-core ◦ OSes did not have thread support at all. https://www.infoq.com/articles/java-virtual-threads/
threads library was user-level • the Solaris system could process only one green thread at a time, • Solaris handled the Java runtime as a many-to-one threading implementation • Java applications could not interoperate with existing MT applications in the Solaris environment. • Java threads could not run in parallel on multiprocessors. • An MT Java application could not harness true OS concurrency for faster applications on either uniprocessors or multiprocessors. Green threads library was replaced with native Solaris threads for Java on the Solaris 2.6 platform; this is carried forward on the Solaris 7 and Solaris 8 platforms. https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqe/
and deliver Java VM features and APIs built on top of them for the purpose of supporting easy-to-use, high-throughput lightweight concurrency and new programming models on the Java platform.”