Udemy Java Multithreading Concurrency course
What happens if one thread depends on another thread? How does Thread B know when Thread A is done, and ready to pass along its result? (L6)
"Busy way" - thread B does a loop while(!threadA.isFinished()) { // Burn CPU cycles } ..... "Better way": ThreadB should go to sleep while ThreadA is working. >> Thread.join() method
Thread.interrupt() (L5)
*** A signal from one Thread to interrupt another Thread *** ** Note that it is a communication between two threads ** ex. // Suppose we are currently in Thread2 Thread1.interrupt(); // Sends a signal from Thread2 to interrupt Thread1
Why do we need to coordinate Threads? (L6)
- Different threads run independently - Order of execution is out of our control - They may run concurrently OR in parallel (Recall, "concurrently" means one core is "multitasking"/rapid switching, and "parallel" means that multiple cores are executing).
When would we prefer a Multiservices architecture instead of a Microthreaded Architecture? (L2)
- If Security/stability is a priority - If tasks are unrelated to each other, just doesn't make sense
3 Reasons to stop a Thread & clean up its resources? (L5)
- If a thread has finished its work, but the application is still running - or, if the thread is misbehaving (such as having an infinite runtime) - or, if we want to stop the application before the thread is done. The rule is, an application cannot be stopped until all threads are stopped.
When would we prefer a Multithreaded architecture instead of a Microservices Architecture? (L2)
- If the tasks share a lot of data - If we want to save time: Switching between threads of the same process is faster (shorted context switches) * Threads are much faster to create and destroy
How would you create a set of functionalities, so that you could apply them all to a group of Threads? See thread.creation > Lec4 > extendThreadEx2 (L4)
// Create an abstract inner class! see private static class AscendingHackerThread extends HackerThread note the constructor calls super(vault); also all private static classes that extend Thread have their own run method, For ex, the run() iterates through all possible passwords, checking if the guess isCorrectPassword. ........it is using the method from the parent class, HackerThread.
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("A critical error happened " + t.getName() + e.getMessage()); } }); (L3)
// Will be thrown if there is an exception in the thread that did not get caught anywhere else
Two reasons for multithreading (L1)
1. Responsiveness 2. Performance
How do you use IntelliJ Debugger to analyze how Threads are running? (L3)
1. Set "break points" by clicking margin and seeing red dot appear 2. Run > Debug 3. Debugger window will pop up. Under that, you can toggle to the Threads tab to see all the threads 4. Once we get to the next break point, all the threads freeze so you can see them individually. You can see the "stack traces" of the current thread and previous thread ** Mine doesn't work yet, perhaps because I need to import some package??
What if one number is very large? How to make sure program still terminates? 2 ways: (L6)
1. Set .join(20000) ms - time to wait or, 2. before thread.start(), say thread.setDaemon(true). Making a thread a Daemon thread means we will be able to terminate the program without having to wait for that thread to get finished.
Multiple threads in a single process share: (Q#1)
1. The heap 2. Code 3. The process's open files 4. The process's metadata
What are two scenarios when we would use Thread.interrupt()? (L5)
1. When the thread is doing a method that throws an InterruptedException, and is interrupted 2. If the thread's code is handling the interruption (interrupt signal) explicitly
What is a Daemon thread? 2 types: (L5)
1. [Under our control] A background task, we do not want it to block our application from terminating ex. a Daemon thread periodically saving the file 2. [Not under our control] Code in a worker thread, we do not want it to block our application from terminating ex. Daemon thread loading external library
What is a Context Switch? (L2)
A Context Switch means: - Stop thread 1 - Schedule Thr 1 out - Schedule Thr 2 in - Start Thr 2 ** Note that this is not cheap, and takes resources in the CPU and memory kind of like the time it takes to gather our thoughts and refocus
In a Process, what does the Main thread contain? (L1)
A Stack & the Instruction Pointer
What is a Process? aka Context? (L1)
An instance of an application. When you run an application, the instance you've created is isolated from any other process in the system. The Process/instance can contain many things like PID Mode, Priority, Files, Data (Heap), Code, and MAIN THREAD (Stack + Instruction Pointer)
What is Responsiveness? (L1)
Concurrency: creates an illusion of multiple tasks running in parallel This means that tasks are completed much faster
in JoinThreadEx, what does the join() method do? (L6)
Forces the main thread to wait until all the factorial threads are finished before printing the result.
Thread Scheduling (L2)
How does the OS decide when to schedule two processes? Suppose we have two applications running, & each app has two processes within it: First come first serve? can cause "starvation" from other threads ex. if the long thread is very long the user will never get to interact! Shortest Job First? Opposite problem - User-related events will go so quickly that the longer tasks will never be executed.
Code: Creating a thread object (L3)
I made a file, UdemyConcurrency.java Under Main.java, I created a new Thread, which takes a new Runnable object, and overrides the run method:
What is Starvation? (L2)
If the threads did not complete in the last epochs, or did not get enough time to run, that is starvation To prevent starvation, the OS will give preference to these threads when doing Thread Scheduling / "Dynamic Priority"
How does the OS design which thread to schedule? (Q#1)
It maintains a dynamic property for each thread (score) to prioritize interactive threads, and avoid starvation for any thread. A very specific but complex algorithm
Microservices Architecture (L2)
Means that instead of having a process with multiple threads (Main Thread 1, Thread2...), you split up the program into two Processes/Contexts Each Process/Context has its own Main thread. This means now the Files, data, code, priority, and other thing are no longer shared. They are unique to the split up Processes
Why do we need context switch? (L2)
Normally, there are way more processes than cores (physical processors) Each Process contains multiple threads So always, the CPU must decide how to switch threads.
Unchecked exceptions & threads (L3)
Normally, unchecked exceptions will bring down the entire thread, unless you handle them in a particular way.
What is Performance? (L1)
Parallelism: with multiple cores, actually runs tasks in parallel This means that tasks are completed much faster
Thread.join() example (L6)
See join.Lec6 > JoinThreadEx Here, we create a private static inner class FactorialThread which extends Thread. That means we can override run() to set private variables to the result of some calculation (helper method factorial) of an input number. (FactorialThread also has isFinished and getResult methods to allow us to access these things from outside the class). Then, in the main, we can create a list of inputNumbers and calculate the factorial of each.
kernel resources
The kernel is the part of an OS that handles the system's resources and the various system calls (requests from software) and how the software and hardware respond to this. The kernel, as the intermediary between the CPU and the process, is the one who allows or not the execution of certain processes... so, to finally answer, the resources allow a process, access to the services of the kernel.
Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("I'm going for a walk"); } }); Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println("I'm going to swim"); } }); thread1.start(); thread2.start(); System.out.println("I'm going home"); ** What is the output for this snippet of code? (Q#3)
The lines can appear in any order. There is no way of knowing for certain!
public static void main(String [] args) { Thread thread = new Thread(new WaitingForUserInput()); thread.setName("InputWaitingThread"); thread.start(); } private static class WaitingForUserInput implements Runnable { @Override public void run() { try { while (true) { char input = (char) System.in.read(); if(input == 'q') { return; } } } catch (IOException e) { System.out.println("An exception was caught " + e); }; } } (Q3) What are the three ways we could stop this application?
The only ways to stop the application are: 1. If the user enters 'q' 2. If we add the line thread.setDaemon(true); to the main method before start() 3. If we forcefully kill the app
Overall structure of the hacker-police example thread.creation > Lec4 > HackerPoliceThreadsEx (L4)
There is a parent class, Thread Two children of Thread are HackerThread and PoliceThread. HackerThread has access to the private Vault object, which means that its two children - AscendingHackerThread and DescendingHackerThread - also have access to the Vault object. All Thread object types will be running simultaneously, until one of them finds a match and calls System.exit.
Within an epoch, how does the OS order each thread? (L2)
Thread scheduling is based on Dynamic Priority. Dynamic Priority = Static Priority + Bonus* *Bonus can be negative. This is set by the developer to give preference to interactive and realtime threads
Why would we want to stop a thread? (L5)
Threads consume memory (even when they aren't doing anything ) and kernel resources When Threads are running, they are consuming time in the CPU time and cache memory
"Thrashing" (L2)
Too many threads! Spending more time in management / context switches than in real productive work
How do we set a priority for a given Thread? (L3)
We can set the static component in our program. Overall, the "Dynamic Priority" will also be determined by a Bonus factor, which is more complicated to do this: thread.setPriority(Thread.MAX_PRIORITY); // Or some other value or constant
(Threads vs Processes) (L2)
When should you create multiple Threads in a program, or when should you create a new program and run it in a new Process.?
"race condition" (L6)
When the main() thread and the factorial() thread are "racing" toward their goals independently We don't know which ones will be in which stages by the time the main() thread is checking for the result.
What are threads ? (hardware) (L1)
When we run an application, the operating system is loaded from the disk into the memory. The operating system lets us interact with the CPU / hard drive so that we can just interact with our user-friendly apps. When we run an application, we create an instance of that application in memory. aka a Process
CTRL-ALT-T
a great way to create a try-catch block in intelliJ!!!
What is the Stack?
a region in memory where local variables are stored and passed into functions
(Q3) Never leave a catch block empty!
add a return statement or clean up code, or some print statement. Good practice!
In a multithreaded application process, what does each thread have? (L1)
each thread has its own Stack & Instruction Pointer However, the rest of the data is shared. This allows each thread to do its own function to its own memory location at any given moment
Github for examples
https://github.com/liv-yaa/udemy-practice
How to coordinate threads with Thread.join() Lecture 6
https://www.udemy.com/java-multithreading-concurrency-performance-optimization/learn/v4/t/lecture/11198682?start=15
How do we use .setDaemon to handle the interrupt exception? (L5)
in the beginning of the program, say: thread.setDaemon(true); // Sets this equal to true thread.interrupt(); // Successful now // This has allowed our app to terminate!
Threads consume _____ resources than processes (L2)
less This is because context switching between threads from the same process is cheaper than context switching between processes
Epoch (L2)
moderately sized pieces that the CPU scheduler separates the runtime pieces into In each epoch, the OS allocates a different time slice for each thread
What is concurrency? (L1)
multiasking You don't even need multiple cores! Like our brains, just switches rapidly from task to task
a new Thread object takes what as a parameter? (L3)
new Runnable() // Lets you override run()
Thread.currentThread().getName() (L3)
prints the name of the current thread
How to use a private static inner class to extend Thread? Alternative to calling new Thread(new Runnable() ... Outside of main, create a new class NewThread extends Thread Then override the run method Then in the main, you can simply create a Thread thread = new NewThread(); (L4)
public class extendThreadEx { public static void main(String[] args) { Thread thread = new NewThread(); thread.start(); } private static class NewThread extends Thread { @Override public void run() { // Code that executes on the new thread System.out.println("Hello from " + Thread.currentThread().getName()); } } }
thread.setName("New Name") (L3)
sets the name of the thread
Thread.sleep(1000) (L3)
sleeps for a given amount of time. Doesn't use CPU while sleeping. change the main method to : psvmain throws InterruptedException {...}
thread.start(); (L3)
starts the thread
what is the Instruction Pointer? (L1)
the pointer that points to the Address of the next instruction to execute
What does Multithreading allow us? (L1)
to use concurrency and parallelism, which brings us more responsiveness and high performance. This means by using multiple threads, we can execute multiple related tasks simultaneously, making the application more responsive. And, executing tasks in parallel MAY achieve higher performance.
Other advantage to using private static class NewThread extends Thread (L4)
we have access to the instance variable plus many other methods in the thread class * Can refer to it simply as this!!