SaveMyCert
Log in
5 of 5 free questions left today·for 30 a day
1Z0-831 · Domain 8

Implementing Multithreading for Concurrent Code Execution practice questions

Implementing Multithreading for Concurrent Code Execution is worth 11% of the 1Z0-831 exam — the 2nd-heaviest of the 10 domains. Platform and virtual threads, executors and scoped values, thread safety with locks and the concurrent API, and concurrent collections and parallel streams. Oracle publishes no domain weights; weight approximates the objective share, with a floor for every section. 6 fully worked examples are further down this page, answers included.

Exam weight
11%
the 2nd-heaviest of the 10 domains
Questions
105
across 3 topics
Free, no account
5/day
a free account allows 30 a day
Explanations
Every option
right and wrong

Build a practice session

5 free questions left today.

Domains

How many?

Mode

Ready when you are

10 fresh questions drawn across 1 of 10 domains, in Learn mode.

Focused review

Every question you answer incorrectly, and every question you flag while practising, is saved here automatically. Finish a session and you can come back to re-drill just those.

6 sample Implementing Multithreading for Concurrent Code Execution questions, fully explained

Questions from the 1Z0-831 bank mapped to domain 8, with the answer key and the reasoning behind every option. None of them repeat the examples on the main 1Z0-831 practice page.

Question 1Implementing Multithreading for Concurrent Code Execution

Given:public class Main { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(() -> System.out.print("run ")); System.out.print(t.getState() + " "); t.start(); t.join(); System.out.print(t.getState() + " "); t.start(); System.out.print("done"); } }What is the result?

Choose one.

  • a
    NEW run TERMINATED run done

    A Thread object can be started only once. After it has terminated it cannot be restarted, so the second start() does not run the task again.

  • b
    NEW run NEW, then the task runs again and done is printed

    A terminated thread never returns to the NEW state. join() waits for the thread to finish; it does not reset it.

  • c
    RUNNABLE run TERMINATED, then an IllegalThreadStateException is thrown

    getState() is called before start(), when the thread is still in the NEW state, not RUNNABLE.

  • d
    NEW run TERMINATED, then an IllegalThreadStateException is thrown Correct

    The first three prints succeed; the second start() on a thread that has already run throws IllegalThreadStateException, so done is never printed.

The concept

A thread moves NEW → RUNNABLE → TERMINATED and can be started exactly once.

Why that’s the answer

Before start() the thread is NEW. start() runs the task, which prints run, and join() waits until the thread is TERMINATED. Calling start() a second time on the same Thread object throws IllegalThreadStateException, an unchecked exception, so the program ends before printing done.

How to reason it out
  1. Read the state before start(): NEW.
  2. start() plus join() runs the task to completion: run is printed and the state is TERMINATED.
  3. Recall that start() may be called only once per Thread object.
  4. The second start() throws IllegalThreadStateException and done is skipped.

Exam tip: Each Thread object is single-use: a second start() throws IllegalThreadStateException.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

Question 2Implementing Multithreading for Concurrent Code Execution

Given:public class Main { public static void main(String[] args) { Thread v = Thread.ofVirtual().unstarted(() -> { }); Thread p = Thread.ofPlatform().unstarted(() -> { }); System.out.print(v.isVirtual() + " " + v.isDaemon()); System.out.print(" " + p.isVirtual() + " " + p.isDaemon()); } }What is the result?

Choose one.

  • a
    true false false false

    Virtual threads are always daemon threads, so v.isDaemon() is true even though the builder never set it.

  • b
    true true false true

    A platform thread inherits the daemon status of the thread that creates it, and the main thread is not a daemon, so p.isDaemon() is false.

  • c
    true true false false Correct

    The virtual thread reports isVirtual() true and is always a daemon; the platform thread inherits main's non-daemon status.

  • d
    true false false true

    This swaps the two rules. A virtual thread is always a daemon, so v.isDaemon() is true; a platform thread built without daemon(...) inherits non-daemon status from main, so p.isDaemon() is false.

The concept

Thread.ofVirtual() and Thread.ofPlatform() return builders for the two kinds of thread; virtual threads are always daemon threads.

Why that’s the answer

isVirtual() reflects how the thread was built and is true for v. Virtual threads are daemon threads by definition, so v.isDaemon() is true. A platform thread created by the builder without daemon(...) inherits the creating thread's daemon status; main is a non-daemon thread, so p prints false false.

How to reason it out
  1. Identify the kind of each thread from its builder.
  2. Recall that every virtual thread is a daemon thread.
  3. Recall that a platform thread inherits daemon status from its creator.
  4. main is non-daemon, so the platform thread is non-daemon.

Exam tip: Virtual threads are always daemons; platform threads inherit daemon status from the creating thread.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

Question 3Implementing Multithreading for Concurrent Code Execution

Given:public class Main { public static void main(String[] args) throws InterruptedException { Thread t = Thread.ofVirtual() .unstarted(() -> System.out.print("work ")); t.setDaemon(false); t.start(); t.join(); System.out.print("done"); } }What is the result?

Choose one.

  • a
    An IllegalArgumentException is thrown Correct

    Thread.setDaemon throws IllegalArgumentException when false is passed for a virtual thread, so nothing is printed.

  • b
    work done

    The task never runs. setDaemon(false) fails before start() is reached, because a virtual thread cannot be made a non-daemon thread.

  • c
    Compilation fails

    setDaemon is a public method of Thread, and t has the static type Thread, so the call compiles. The problem only shows up at runtime.

  • d
    An IllegalThreadStateException is thrown

    That exception is for calling setDaemon on a thread that has already started. Here t is still unstarted; the value false itself is rejected.

The concept

Virtual threads are always daemon threads, and Thread.setDaemon enforces it.

Why that’s the answer

The code compiles because setDaemon(boolean) is declared on Thread. At runtime, Thread.setDaemon(false) on a virtual thread throws IllegalArgumentException (the JDK message is "'false' not legal for virtual threads"). IllegalThreadStateException would only arise for a thread that is already alive, which t is not. The exception propagates out of main before start(), so neither work nor done is printed.

How to reason it out
  1. Check that the code compiles: setDaemon is a Thread method.
  2. Recall that virtual threads must be daemon threads.
  3. Distinguish the two possible exceptions: the argument is illegal, the state is fine.
  4. The exception escapes main before anything prints.

Exam tip: Passing false to setDaemon on a virtual thread throws IllegalArgumentException; on a started thread setDaemon throws IllegalThreadStateException.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

Question 4Implementing Multithreading for Concurrent Code Execution

Given:import java.util.concurrent.*; public class Main { public static void main(String[] args) { try (var es = Executors.newSingleThreadExecutor()) { // line n1 } } }Which two statements, each inserted alone at line n1, compile? (Select TWO.)

Choose TWO.

  • a
    es.submit(() -> { Thread.sleep(10); });

    With no return value the lambda can only be a Runnable, whose run() declares no checked exceptions, so the unhandled InterruptedException is a compile error.

  • b
    es.submit(() -> { Thread.sleep(10); return 1; }); Correct

    The block returns a value, so the lambda is a Callable<Integer>, and Callable.call() is declared to throw Exception, which covers InterruptedException.

  • c
    es.submit(() -> System.out.print("x")); Correct

    print returns void, so the lambda matches Runnable; it throws no checked exception, so submit(Runnable) compiles.

  • d
    es.execute(() -> { Thread.sleep(10); return 1; });

    execute accepts only a Runnable, and a Runnable lambda cannot return a value, so the call does not compile.

  • e
    Callable<Integer> c = () -> { System.out.print("x"); };

    Callable<Integer>.call() must return an Integer, and this block has no return statement, so the lambda is incompatible.

The concept

Runnable.run() returns nothing and throws no checked exceptions; Callable.call() returns a value and may throw any Exception.

Why that’s the answer

The compiler picks the functional interface from the lambda body. A block that returns a value fits Callable, and call() throws Exception, so Thread.sleep's InterruptedException needs no handler. A void body fits only Runnable, so a checked exception in it must be caught. execute(Runnable) has no Callable overload, and a Callable lambda must return a value on every path.

How to reason it out
  1. Classify each lambda body as value-returning or void.
  2. Match value-returning bodies to Callable and void bodies to Runnable.
  3. Check checked exceptions: allowed in call(), not in run().
  4. Check that execute only takes a Runnable.

Exam tip: Need a result or a checked exception? Use Callable with submit; Runnable can do neither.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

Question 5Implementing Multithreading for Concurrent Code Execution

Given:import java.util.concurrent.*; public class Main { public static void main(String[] args) throws Exception { ExecutorService es = Executors.newFixedThreadPool(2); Future<?> f1 = es.submit(() -> System.out.print("A ")); Future<String> f2 = es.submit(() -> "B"); System.out.print(f1.get() + " " + f2.get()); es.shutdown(); } }What is the result?

Choose one.

  • a
    A A B

    get() returns the task's result, not what it printed. A Runnable has no result, so its Future yields null.

  • b
    A B

    f1.get() still returns a value that is concatenated into the output. For a Runnable that value is null, which prints as the word null.

  • c
    A null B Correct

    The Runnable task prints A and its Future completes with null; the Callable's Future holds B.

  • d
    Compilation fails

    Future<?> is a valid target for submit(Runnable), and get() on a Future<?> returns Object, which string concatenation accepts.

The concept

submit(Runnable) returns a Future whose get() returns null on success; submit(Callable<T>) returns a Future<T> holding the call's result.

Why that’s the answer

The first lambda calls print, which returns void, so it is a Runnable and its Future completes with null. The second lambda returns "B", so it is a Callable<String>. f1.get() blocks until A has been printed, and then main prints null, a space and B.

How to reason it out
  1. Decide which lambda is a Runnable and which a Callable.
  2. Recall that a Runnable's Future yields null.
  3. Note that f1.get() waits, so A is printed first.
  4. Concatenate: A, then null B.

Exam tip: A Future from submit(Runnable) completes with null.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

Question 6Implementing Multithreading for Concurrent Code Execution

Given:import java.util.concurrent.*; public class Main { public static void main(String[] args) { try (var es = Executors.newSingleThreadExecutor()) { int d = 0; Future<Integer> f = es.submit(() -> 10 / d); try { System.out.print(f.get()); } catch (ExecutionException e) { System.out.print("EE:" + e.getCause().getClass().getSimpleName()); } catch (InterruptedException e) { System.out.print("IE"); } } } }What is the result?

Choose one.

  • a
    EE:ArithmeticException Correct

    The task's ArithmeticException is stored in the Future, and get() rethrows it wrapped in an ExecutionException whose cause is the original.

  • b
    EE:ExecutionException

    The caught exception is the ExecutionException; its getCause() is the exception the task threw, which is ArithmeticException.

  • c
    An ArithmeticException is thrown out of main

    The exception happens on the pool thread and is captured by the Future. get() reports it as an ExecutionException, which the catch block handles.

  • d
    Nothing is printed

    A task's exception is not lost: get() surfaces it, and the catch block prints the cause's simple name.

The concept

An exception thrown by a submitted task is captured in its Future and rethrown by get() as an ExecutionException.

Why that’s the answer

10 / d with d equal to 0 throws ArithmeticException on the executor's thread. submit() catches it and completes the Future exceptionally. f.get() then throws ExecutionException with the ArithmeticException as its cause, so the first catch block prints EE:ArithmeticException.

How to reason it out
  1. Locate where the exception is thrown: inside the task.
  2. Recall that submit() captures task exceptions in the Future.
  3. get() wraps the failure in ExecutionException.
  4. getCause() returns the original ArithmeticException.

Exam tip: Future.get() reports a failed task as ExecutionException; the real exception is its cause.

Java Threads, Virtual Threads, Executors and Scoped Values (1Z0-831) — the lesson that teaches this.

What 1Z0-831 domain 8 tests, topic by topic

The official exam guide breaks Implementing Multithreading for Concurrent Code Execution into 3 topics. The question bank follows the same split, so a weak topic shows up as a cluster of misses you can go back and read.

Published 1Z0-831 practice questions per topic in Implementing Multithreading for Concurrent Code Execution
TopicWhat it coversQuestions
Platform and virtual threads, executors and scoped valuesOfficial 1Z0-831 objective 8.1: "Create both platform and virtual threads. Use Runnable and Callable objects, manage the thread lifecycle, use different Executor services and concurrent API to run tasks, and use scoped values to share immutable context."35
Thread-safe code with locks and the concurrent APIOfficial 1Z0-831 objective 8.2: "Develop thread-safe code, using locking mechanisms and concurrent API."35
Concurrent collections and parallel streamsOfficial 1Z0-831 objective 8.3: "Process Java collections concurrently and utilize parallel streams."35
Total105

Revise Implementing Multithreading for Concurrent Code Execution before you drill it

Other 1Z0-831 domains

Implementing Multithreading for Concurrent Code Execution: your questions

Implementing Multithreading for Concurrent Code Execution is domain 8 of the 1Z0-831 exam guide and carries 11% of the scored content — the 2nd-heaviest of the 10 domains. On a 50-question paper that works out to roughly 6 questions, though Oracle does not publish an exact per-domain count and individual exam forms vary.

Source

The domain weight and topic list on this page come from the official 1Z0-831 exam guide.