Java Multithreading / Concurrency - terms
Thread - create & start a thread
*Thread thread = new Thread();* *thread.start();* //using start method above. - The start method of the Thread class starts a new thread that executes the run method of the associated Runnable object.
Thread - time slicing vs preemptive scheduling
*Time slicing* - A task executes for a predefined slice of time and then reenters the pool of ready tasks. The scheduler then determines which task should execute next, based on priority and other factors. --------------------------------------------------- *preemptive scheduling* - a task with a higher priority interrupts a task with a lower priority and executes itself.
Thread - states - Runnable
- By invoking the start method t.start(); - Will run when OS gives it thread time (time splicing). - Preemptive scheduling gives each thread a slice of time to run.
Thread - Daemon Thread
- Daemons are threads that server other threads - Timer threads are daemon threads - Call *t.setDaemon(true)* to set a thread as a daemon. - When only daemon thread remain, the VM exits as there is no reason to have service thread alive if there is nothing to serve. - Threads must be set to daemon before they start.
Thread - states - Blocked
- Goes to sleep by calling sleep method. - Blocking on I/O, basically waiting for I/O to finish. - Tries to get a lock on a currently locked resource. - Waiting on a condition to become true. - The suspend method is called on the thread, (deprecated and should not be used). Threads move out of blocked state to a runnable state: 1. Sleep is over with. 2. I/O completed. 3. Other thread relinquishes a lock this thread was waiting for. 4. A signal that a condition has changed. 5. Resume is called after suspend.
Tread - states
4 thread states 1. New 2. Runnable 3. Blocked 4. Dead
Critical section
A critical section is a section of code that is executed by multiple threads and where the sequence of execution for the threads makes a difference in the result of the concurrent execution of the critical section.
Thread - Deadlock or Deadly Embrace
A deadlock is when two or more threads are blocked waiting to obtain *locks* that some of the other threads in the deadlock are holding. - Deadlock can occur when multiple threads need the same *locks*, at the same time, but obtain them in different order.
Thread - Lock
A lock is a thread synchronization mechanism like synchronized blocks except locks can be more sophisticated than Java's synchronized blocks. - Locks are created using synchronized blocks, so it is not like we can get totally rid of the synchronized keyword. - The Java library defines a Lock interface and several classes that implement this interface. - The *ReentrantLock class* is the most commonly used lock class. - When a thread calls the lock method, it owns the lock until it calls the unlock method. (If a thread calls lock while another thread owns the lock, it is temporarily deactivated). - The thread scheduler periodically reactivates such a thread so that it can again try to acquire the lock. - Locks are used to ensure that shared data are in a consistent state when several threads access them. *package java.util.concurrent.locks*
Amdahl's Law Defined
A program (or algorithm) which can be parallelized can be split up into two parts: A part which cannot be parallelized A part which can be parallelized
Thread - Race condition
A race condition is a special condition that may occur inside a critical section. (multiple threads sharing access to a common object). - Occur only if multiple threads are accessing the same resource, and one or more of the threads write to the resource. - Race conditions can be avoided by proper thread synchronization in critical sections - A race condition occurs if the effect of multiple threads on shared data depends on the order in which the threads are scheduled. - To solve race condition problems,use a lock object. The lock object is used to control the threads that want to manipulate a shared resource
Thread - Sleep vs Await
A sleeping thread is reactivated when the sleep delay has passed. A waiting thread is only reactivated if another thread has called signalAll or signal.
Thread - livelock
A thread often acts in response to the action of another thread. - If the other thread's action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They're still blocking each other, so..
Thread - terminates
A thread terminates when its run method terminates. - However, sometimes you need to terminate a running thread. - For example, you may have several threads trying to find a solution to a problem. As soon as the first one has succeeded, you may want to terminate the other ones. - Instead of simply stopping a thread, you should notify the thread that it should be terminated. The thread needs to cooperate, by releasing any resources that it is currently using and doing any other required cleanup. In other words, a thread is in charge of terminating itself. - JaVA does not force a thread to terminate when it is interrupted.
Blocking Concurrency Algorithms
A: Performs the action requested by the thread - OR B: Blocks the thread until the action can be performed safely
Non-blocking Concurrency Algorithms
A: Performs the action requested by the thread - OR B: Notifies the requesting thread that the action could not be performed
Thread - Lock
All code that manipulates the shared resource is surrounded by calls to lock and unlock the lock object: *balanceChangeLock.lock();* *try {* *Manipulate the shared resource }* *finally { * *balanceChangeLock.unlock(); }* - When a thread calls *lock*, it owns the lock until it calls *unlock*. - A thread that calls *lock* while another thread owns the lock is temporarily deactivated. - Thread scheduler periodically reactivates thread so it can try to acquire the lock. - Eventually, waiting thread can acquire the lock.
Synchronized blocks (definition)
All synchronized blocks synchronized on the same object can only have one thread executing inside them at the same time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
Concurrency (multithreaded programs)
An application is making progress on more than one task at the same time (concurrently). - a process is sort of what your program is. - a thread is running inside the process - The Java Virtual Machine executes each thread in the program for a short amount of time.
Parallelism (multithreaded programs)
An application splits its tasks up into smaller subtasks which can be processed in parallel, for instance on multiple CPUs at the exact same time.
Thread - await
Calling *await* on a condition object makes the current thread wait and allows another thread to acquire the lock object. - When a thread calls await, it is not simply deactivated in the same way as a thread that reaches the end of its time slice. - Instead, it is in a blocked state, and it will not be activated by the thread scheduler until it is unblocked. - To unblock, another thread must execute the *signalAll* method on the *same condition object*.
Thread - await
Calling await - Makes current thread wait - Allows another thread to acquire the lock object To unblock, another thread must execute *signalAll* on the same condition object : *sufficientFundsCondition.signalAll();*
Thread - safe
Code that is safe to call by multiple threads simultaneously is called thread safe. If a piece of code is thread safe, then it contains no race conditions.
Thread - condition
Condition interface: - Represents a condition variable associated with a lock - Allows one thread to suspend execution (to "wait") until notified by another thread - The suspended thread releases the lock
Thread - thread pools
Creating a large number of shortlived threads is inefficient as threads are managed by the OS - creating a bunch of threads that are already open and live, and then bring object in when it is needed. Runnable r1 = new GreetingRunnable("..."); Runnable r2 = new GreetingRunnable("..."); ExecutorService pool = Executors.newFixedThreadPool(MAX_THREADS); Pool.execute(r1); Pool.execute(r2);
The Thread Control Escape Rule
If a resource is created, used and disposed within the control of the same thread, and never escapes the control of this thread, the use of that resource is thread safe.
Thread - Runnable Interface Implementation
Implementing Runnable interface does not create a Thread object, it only defines an entry point for threads in your object. It allows you to pass the object to the Thread(Runnable implementation) constructor. To run this implementation class: 1. create a Thread object, 2. pass Runnable implementation class object to its constructor. 3. Call start() method on thread class to start executing run() method. (The problem with creating a class that extends the Thread class is that a class can have one superclass. What if you'd rather have your thread object extend some other class? In that case, you can create a class that implements the Runnable interface rather than extends the Thread class.)
Types of Synchronized blocks
Instance methods public synchronized void add(int value){ this.count += value;} Static methods public static synchronized void add(int value){ count += value;} Code blocks inside instance methods public void add(int value){ synchronized(this){ this.count += value; } } Code blocks inside static methods public static void log2(String msg1, String msg2){ synchronized(MyClass.class){ log.writeln(msg1); log.writeln(msg2); }}
Thread - starvation
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. - This happens when shared resources are made unavailable for long periods by "greedy" threads. - For example, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.
Thread - signalAll
The *signalAll* method unblocks all threads waiting on the condition. - They can then compete with all other threads that are waiting for the lock object. - Eventually, one of them will gain access to the lock, and it will exit from the await method.
ThreadLocal class
The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread private ThreadLocal myThreadLocal = new ThreadLocal(); myThreadLocal.set("A thread local value"); String threadLocalValue = (String) myThreadLocal.get();
Thread - interrupt method
The java.lang.Thread.interrupt() method interrupts this thread. - Interrupting a thread that is not alive need not have any effect. - interrupted status is initially "false" When a thread is interrupted by some other thread through a call to Thread.interrupt(), one of two things happens. 1. If that thread is executing a low-level interruptible blocking method like Thread.sleep(), Thread.join(), or Object.wait(), it unblocks and throws InterruptedException. 2. Otherwise, interrupt() merely sets the thread's interruption status. Code running in the interrupted thread can later poll the interrupted status to see if it has been requested to stop what it is doing; the interrupted status can be read with Thread.isInterrupted() and can be read and cleared in a single operation with the poorly named Thread.interrupted(). *interruption is a way of politely asking another thread to stop what it is doing if it wants to, at its convenience*
Thread - run method
The run method can check whether its thread has been interrupted by calling the *interrupted method.* - The run method can check whether that flag has been set, by calling the static interrupted method. In that case, it should do any necessary cleanup and exit.
Thread - sleep
The sleep method puts the current thread to sleep for a given number of milliseconds. - There is, however, one technical problem. Putting a thread to sleep is potentially risky— a thread might sleep for so long that it is no longer useful and should be terminated. - to terminate a thread, you interrupt it. - When a sleeping thread is interrupted, an InterruptedException is generated. You need to catch that exception in your run method and terminate the thread. - if a thread is sleeping, it can't execute code that checks for interruptions. Therfore the sleep method is termintated with an InterruptedException whenever a sleeping thread is interrupted.
Thread - time slice
The thread scheduler runs each thread for a short amount of time, called a *time slice*.
Thread - scheduler
The thread scheduler runs each thread for a short amount of time, called a *time slice*. - Then the scheduler activates another thread. - There will always be slight variations in running times - especially when calling operating system services (e.g. input and output). - There is no guarantee about the order in which threads are executed.
Thread - stop
There are two ways through which you can stop a thread in java. 1. use boolean variable.... stop() 2. use interrupt() method. Stop( ) is *deprecated*, because it is unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.)
Thread - states - Dead
Threads are dead for 2 reasons: - Run exits normally. - Can use the stop method to kill a thread however this is deprecated as it can leave objects in an indeterminate state.
Thread - Deadlock - conditional object & await
To overcome deadlocks... create a *conditional object*. - Condition objects allow a thread to temporarily release a lock, and to regain the lock at a later time. - Each condition object belongs to a specific lock object. public class BankAccount { public BankAccount() { balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); ......... } ..... private Lock balanceChangeLock; private Condition sufficientFundsCondition; } // As long as test is not fulfilled, call *await* on the condition object: public void withdraw(double amount) { balanceChangeLock.lock(); try { while (balance < amount) sufficientFundsCondition.await(); ... } finally { balanceChangeLock.unlock(); } }
Thread - signalAll
To unblock, another thread must execute *signalAll* on the same condition object : *sufficientFundsCondition.signalAll();* -signalAll unblocks all threads waiting on the condition - signal: randomly picks just one thread waiting on the object and unblocks it - signal can be more efficient, but you need to know that every waiting thread can proceed
Thread - isAlive
Use isAlive method to determine state of thread - True if runnable or blocked - False if new or dead.
Thread - states - New
When a thread is created but no running yet Runnable r = new BallRunnable(b, comp); Thread t = new Thread(r); Bookkeeping occurs before the thread can run.
Thread - Race Conditions
When threads share a common object, they can conflict with each other. *SEE BANK ACCOUNT THREADING , SAMPLE PROGRAM*
Thread
a program unit that is executed concurrently with other parts of the program. 1. To run a thread, implement a class that implements the Runnable interface. (That interface has a single method called run.) 2. Then place the code for your task into the run method of your class. - sometimes called lightweight processes. - every program starts with at least 1 thread, called main thread..... the main thread can create additional threads.
Concurrency vs. Parallelism
concurrency is related to how an application handles multiple tasks it works on. parallelism is related to how an application handles each individual task. 1. concurrent, but not parallel. This means that it processes more than one task at the same time, but the tasks are not broken down into subtasks. 2. parallel but not concurrent. This means that the application only works on one task at a time, and this task is broken down into subtasks which can be processed in parallel. 3. neither concurrent nor parallel. This means that it works on only one task at a time, and the task is never broken down into subtasks for parallel execution. 4. both concurrent and parallel, in that it both works on multiple tasks at the same time, and also breaks each task down into subtasks for parallel execution.
volatile keyword
is used to mark a Java variable as "being stored in main memory". More precisely that means, that every read of a volatile variable will be read from the computer's main memory, and not from the CPU cache, and that every write to a volatile variable will be written to main memory, and not just to the CPU cache.
Thread - thread priorities (thread properties)
method allows for increasing or decreasing a thread priority: *setPriority(int)* - Can use a value between 1 and 10 constants include: (high priority is 10.... low priority is 1) MIN_PRIORITY of 1, MAX_PRIORITY of 10 and NORM_PRIORITY of 5 - Scheduler prefers to pick thread with highest priority. - Priorities are system dependent such as linux ignores the priorities or windows has 7 levels of priorities. - So treat priorities as a suggestion never structure your code that it depends on priority levels. - Be careful of starvation when using priorities. - Yield method - causes thread to block and allow other thread with same or high priority to run.
Thread Subclass
public class MyThread extends Thread { public void run(){ System.out.println("MyThread running"); } } public static void main(String[] args){ Thread thread = new Thread(){ public void run(){ System.out.println("Thread Running"); } } thread.start(); }
Separate synchronized blocks (example)
public class TwoSums { private int sum1 = 0; private int sum2 = 0; private Integer sum1Lock = new Integer(1); private Integer sum2Lock = new Integer(2); public void add(int val1, int val2){ synchronized(this.sum1Lock){ this.sum1 += val1; } synchronized(this.sum2Lock){ this.sum2 += val2; }}}
Synchronized block (example)
public class TwoSums { private int sum1 = 0; private int sum2 = 0; public void add(int val1, int val2){ synchronized(this){ this.sum1 += val1; this.sum2 += val2; } } }
Thread - suspend
suspend( ) is *deprecated*, because Thread.suspend is inherently deadlock-prone. If the target thread holds a lock on the monitor protecting a critical system resource when it is suspended, no thread can access this resource until the target thread is resumed. If the thread that would resume the target thread attempts to lock this monitor prior to calling resume, deadlock results. Such deadlocks typically manifest themselves as "frozen" processes. (could replace with "suspended"....... threadSuspended)
Thread - Synchronizing
to solve *Thread - Race* problems, use a *lock object*.