Basis knowledge of threading in Java
Thread execution is preemptive,that says any running thread could be hanged up at anytime, then the other thread can run.
thread is a smallest unit of a process, thread is independent.
Differences and connection between thread and process
- A process is a program that under excution,and thread is a segment of a process, it is called a lightweight process.
- A process is responsible for thread scheduling and managing.
- Process takes more time on context switching, thread takes less time
- Process is isolated while thread shares memory
- Process has its own Process Control Block, Stack and Address Space. Thread has Parents’ Process Control Block , its own Thread Control Block and Stack and common Address space and local variables.
Two ways to create thread
- ** create thread class by extending the Thread class**
-
define a subclass of Thread Class, override the run() method, the method body represent the task of this thread
-
create a thread object , which means a instance of the subclass of thread
-
execute the thread using start() method.
public class ThreadTest extends Thread { // 重写run()方法,即线程执行体 public void run() { for (int i = 0; i < 100; i++) { System.out.println(this.getName() + " " + i); } }
public static void main(String[] args) { //创建并启动线程Thread-0 new ThreadTest().start();// in runnable state //Thread-1 new ThreadTest().start(); for (int i = 0; i < 100; i++) { //打印main线程 System.out.println(Thread.currentThread().getName() + " " + i); if (i == 20) { //Thread-2 new ThreadTest().start();// in runnable state } } }}
2. create thread class by implementing the Runable interface
- implements the Runable class, override the run() method
- create the instance object of this class by new key word, and then pass the object as a target to the Thread, we finally get the real thread object look at the code, rt is the target that we pass to the constructor.
RunnableTest rt = new RunnableTest();//target
new Thread(rt,"新线程1").start();// new thread(rt,"xx") is the real thread object,runnable只是thread类的target
-
invoked the start() method of this thread object
public class RunnableTest implements Runnable{ private int i;
@Override public void run() { for (; i < 500; i++) { //实现Runnable接口时 //只能用Thread.currentThread()方法获取当前线程 System.out.println(Thread.currentThread().getName() + " " + i); } } public static void main(String[] args) { RunnableTest rt = new RunnableTest();//target new Thread(rt,"新线程1").start();// new thread(rt,"xx") is the real thread object new Thread(rt,"新线程2").start(); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " +i); } //使用Lambda表达式 Runnable lambdaTest = () -> System.out.println(Thread.currentThread().getName() + " Lambda"); new Thread(lambdaTest,"Lambda线程").start(); }}
It is always better to create thread by implementing the Runable Class. Since we can still extend other class and we can share the target with multiple threads which are do the same jobs.
Life cycle of a thread
Ways to control the execution of a thread
- join() method: it waits for a thread to die, If t is a Thread object whose thread is currently executing, then t.join() will make sure that t is terminated before the next instruction is executed by the program. when t is terminated, it will return and call notifyAll() to wait up the main thread ( the thread which execute the t thread) .
- Deamon Thread : A thread provide supports for other threads. when all other threads terminate, the deamon thread will be terminated automatically. use setDeamon(true) to set the thread to deamon thread.
- sleep() method: it belongs to thread and it is a static method. when a thread invoked sleep() method, the thread will be blocked. it will release the CPU resources, but it will not release the lock. after sleep is done, the thread will be in Runable state.
- yield() method: it also belongs to thread and it a static method. unlike sleep(), when yield() is invoked, the thread will not be blocked, but it will turn the thread to runnable state, the scheduler will reschedule it again based on the priority.
The concept and necessity of thread synchronization
How to use synchronized to achieve thread synchronization
How to use Lock Object to achieve thread synchronization
Use Object methods to achieve Thread communication
1. synchronized block
synchronized(obj){
....}
//obj is the synchronized monitor,before the thread execute,
it has to gain the lock of this monitor
2. synchronized method. while use synchronized keyword to describe the method, the monitor will be 'this'
wait() method : it belongs to Object, when it is invoked, it will pause the thread and release the synchronized monitor
Use condition variables to achieve Thread communication
Deadlock
Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.
How to avoid deadlock:
- allocate resources orderly
- set up a time limit to release the resources
- banker algorithem
implement Callable interface to create thread
Callable and Future: Callable is also an interface like Runable, it has call() method, call() method can return value and throw exception;Future is an interface used to store a result obtained from a different thread, its implemented class is called FutureTask. FutureTask implements Future interface and Runable interface, it can be the target of Thread class
// Java program to illustrate Callable and FutureTask // for random number generation import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; class CallableExample implements Callable { public Object call() throws Exception { Random generator = new Random(); Integer randomNumber = generator.nextInt(5); Thread.sleep(randomNumber * 1000); return randomNumber; } } public class CallableFutureTest { public static void main(String[] args) throws Exception { // FutureTask is a concrete class that // implements both Runnable and Future FutureTask[] randomNumberTasks = new FutureTask[5]; for (int i = 0; i < 5; i++) { Callable callable = new CallableExample(); // Create the FutureTask with Callable randomNumberTasks[i] = new FutureTask(callable); // As it implements Runnable, create Thread // with FutureTask Thread t = new Thread(randomNumberTasks[i]); t.start(); } for (int i = 0; i < 5; i++) { // As it implements Future, we can call get() System.out.println(randomNumberTasks[i].get()); // This method blocks till the result is obtained // The get method can throw checked exceptions // like when it is interrupted. This is the reason // for adding the throws clause to main } } }
How to use thread pool and what it does
reference: tech.meituan.com/2020/04/02/…
How to use ThreadLocal class and what it does
ThreadLocal is a class to create thread local variable, it only has 3 public methods
every thread that uses A ThreadLocal type variable, this variable will create a copy for every thread. ThreadLocal and synchronization are different. ThreadLocal isolates the data for multiple thread. it actually avoid the data or resources sharing.
Actually,we can considerThreadLocal<font face="-apple-system, system-ui, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif" color="#333333"><span style="font-size: 16px; background-color: rgb(255, 255, 255);"> as a </span></font>``Map<Thread, Object>:when every thread to access the ThreadLocalvariable,it always use Thread itself as key
Object threadLocalValue = threadLocalMap.get(Thread.currentThread());
therefore,ThreadLocal actually allocate an independent storage space for every thread.