Concurrency Flashcards
thread
the smallest unit of execution that can be scheduled by the operating system
process
a group of associated threads that execute in the same, shared environment
Shared Environment
the threads in the same process share the same memory space and can communicate directly with one another
Concurrency
The property of executing multiple threads and processes at the same time
Context Switch
the process of storing a thread’s current state and later restoring the state of the thread to continue execution
thread priority
a numeric value associated with a thread that is taken into consideration by the thread scheduler when determining which threads should currently be executing
Values of
Thread.MIN_PRIORITY
Thread.NORM_PRIORITY
Thread.MAX_PRIORITY
1
5
10
Note: If two threads have the same priority, the thread scheduler will arbitrarily choose the one to process first in most situations.
Runnable
a functional interface that takes no arguments and returns no data.
commonly used to de ne the work a thread will execute, separate from the main application thread.
@FunctionalInterface public interface Runnable { void run();
}
How to execute a task with the Thread class
First you define the Thread with the corresponding task to be done. Then you start the task by using the Thread.start() method.
Two ways to define the task for a Thread instance
1) Provide a Runnable object or lambda expression to the Thread constructor (preferred method):
public class PrintData implements Runnable { public void run() { //print something } public static void main(String[] args) { (new Thread(new PrintData())).start(); } }
2) Create a class that extends Thread and overrides the run() method:
public class ReadInventoryThread extends Thread { public void run() { System.out.println("Printing zoo inventory"); } public static void main(String[] args) { (new ReadInventoryThread()).start(); } }
What order are threads processed in?
Whatever the thread scheduler decides
There is no guarantee that the thread you start first will be processed before the second. They could be broken up over time switching between threads too. Shit’s nuts and unpredictable.
A reason to prefer extending Thread instead of implementing Runnable when creating your own thread
If you need to define your own Thread rules upon which multiple tasks will rely, such as a priority Thread, extending Thread may be preferable.
3 reasons to prefer implementing Runnable instead of extending Thread when creating your own thread
1) Implementing Runnable lets you extend another class.
2) Implementing Runnable is often a better object-oriented design practice since it separates the task being performed from the Thread object performing it.
3) Implementing Runnable allows the class to be used by numerous Concurrency API classes.
Polling
the process of intermittently checking data at some fixed interval
Thread.sleep(long mills)
Requests the current thread of execution rest for a speci ed number of milliseconds. When used inside the body of the main() method, the thread associated with the main() method will pause, while the separate thread will continue to run.
What exception might Thread.sleep() throw?
InterruptedException
ExecutorService
An interface that includes numerous useful features, such as thread pooling and scheduling, which would be cumbersome for you to implement in every project. Therefore, it is recommended that you use this framework anytime you need to create and execute a separate task, even if you need only a single thread.
How to create an instance of ExecutorService for a single thread and execute the thread. Then close the ExecutorService.
ExecutorService service = null; try { service = Executors.newSingleThreadExecutor();
service.execute(() -> System.out.println("Running")); } finally { service.shutdown(); }
If a single-thread ExecutorService instance is used to execute multiple threads, what order will they be executed in?
The order in which they are added to the ExecutorService
What will happen if you don’t call shutdown() on your executor?
Your application will never terminate.
RejectedExecutionException
Thrown when a new task is submitted to the thread executor while it is shutting down
isShutdown() and isTerminated()
isShutdown() will return true while an executor is being shut down and after it shuts down
isTerminated() will return false while an executor is being shut down and return true after it shuts down
Difference between shutdown() and shutdownNow()
shutdown() will finish executing any tasks that have already been submitted to the executor
shutdownNow() will attempt to cancel any currently running tasks or tasks that are queued up. Also returns a List of tasks that were submitted to the thread executor but that were never started.
void execute(Runnable command)
Executes a Runnable task at some point in the future
Future> submit(Runnable task)
Executes a Runnable task at some point in the future and returns a Future representing the task
Future submit(Callable task)
Executes a Callable task at some point in the future and returns a Future representing the pending results of the task
List> invokeAll( Collection extends Callable> tasks)
Executes the given tasks, synchronously returning the results of all tasks as a Collection of Future objects, in the same order they were in the original collection
T invokeAny( Collection extends Callable> tasks)
Executes the given tasks, synchronously returning the result of one of finished tasks, cancelling any unfinished tasks
Which method is preferred, submit() or execute()?
submit()
Mostly just cuz they basically do the same thing but submit returns a Future object that can be used
Future method
boolean isDone()
Returns true if the task was completed, threw an exception, or was cancelled
Future method
boolean isCancelled()
Returns true if the task was cancelled before it completely normally.
Future method
boolean cancel()
Attempts to cancel execution of the task.