1. Thread overview
1.1 threads and processes
- A process is a program in the running process, and has a certain independent function
- Concurrency : Only one instruction can be executed at the same time, but multiple process instructions are executed in rapid rotation
- Parallel : multiple instructions are executed simultaneously on multiple processors
- The thread is the execution unit of the process
1.2 Advantages of multithreading
- Memory cannot be shared between processes, but it is very easy between threads
- When the system creates a process, it needs to reallocate system resources for the process, but the cost of creating threads is much smaller, so it is more efficient to use multithreading
- Java language has built-in multi-threading function
2. Thread creation and startup
2.1 Inherit Thread
public class FirstThread extends Thread {
private int i;
@Override
public void run() {
for(i = 0; i < 50; i ++){
System.out.println(this.getName() + "" + i);
}
}
public static void main(String[] args){
FirstThread ft = new FirstThread();
for(int i =0; i < 100;i ++){
System.out.println(Thread.currentThread().getName() + "" + i);
if(i == 20) {
ft.run();
}
}
}
}
2.2 Implement Runnable interface
public class FirstThread implements java.lang.Runnable {
private int i;
public void run() {
for(i = 0; i < 50; i ++){
System.out.println(Thread.currentThread().getName()+ "" + i);
}
}
public static void main(String[] args){
FirstThread ft = new FirstThread();
for(int i =0; i < 100;i ++){
System.out.println(Thread.currentThread().getName() + "" + i);
if(i == 20) {
ft.run();
}
}
}
}
2.3 Use Callable and Future
Callable
The interface provides acall()
method that can be used as a thread execution body, thecall()
method has a return value and can declare to throw an exception- Java5 provides an
Future
interface to represent the return valueCallable
of thecall()
method in theFuture
interface , and provides anFutureTask
implementation class for the interface Future
Method of interface definition:
Method name | effect |
---|---|
boolean cancel(boolean mayInterruptIfRunning) |
Attempt to cancel the task Future associated thereCallable |
V get() |
Return the return value of the method in the Callable task. call This method will cause the thread to block, and it will be obtained after the child thread is executed. |
V get(long timeout, TimeUnit unit) |
Return the return value Callable of the call method in the task . This method allows the program to block at most timeout and the unit specified time, and if the Callable task has not returned a value after the specified time, TimeoutException an exception is thrown |
boolean isCancelled() |
Callable Whether the task in is cancelled |
boolean isDone() |
Callable Whether the task in is completed |
public class CallableDemo {
public static void main(String[] args){
FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)() -> {
int i = 0;
for( ; i < 100; i++){
System.out.println(i);
}
return i;
});
new Thread(task).start();
try {
System.out.println(task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
2.4 Comparison of three ways to create threads
Runnable
And Callable
advantages and disadvantages:
- Thread class implements only
Runnable
,Callable
the interface, you can inherit from other classes - In the case of Runnable and Callable, multiple threads can share the same
target
object, so it is very suitable for multiple same threads to process the same resource - Programming is slightly more complicated, if you need to access the current thread, you must use
Thread.currentThread()
Thread
Advantages and Disadvantages:
- The thread class has inherited the
Thread
class, so it can no longer inherit from other parent classes - Simple to write, if you need to access the current thread,
this
use
3. Thread life cycle
3.1 New and ready state
new
The statement is only allocated memory by the Java virtual machine, and it does not show any dynamic characteristics of threads- If you directly call the
run
method of the inherited class , there will only beMainActivity
, and you cannotgetName
get the name of the current execution thread, but need to useThread.currentThread().getName()
- After calling the
run
method, the thread is no longer in the newly created state
3.2 Running and blocking state
- When the number of threads is greater than the number of processors, there are multiple threads rotating on the same CPU
- Cooperative scheduling strategy : Only when a thread calls the
sleep()
ORyield()
method will it give up the occupied resources-that is, the thread must actively give up the occupied resources - Preemptive scheduling strategy : The system allocates a small period of time to each executable thread to process the task. When the task is completed, the system will deprive the thread of resources occupied
- The blocked thread will re-enter the ready state when appropriate
3.3 State of death
- Test thread death available
isAlive()
- The thread that is dead cannot run again, otherwise
IllegalThreadStateException
an exception will be thrown
4. Control thread
4.1 join thread
- In the
MainActivity
callA.join()
, itMainActivity
is blocked, A thread of execution afterMainActivity
it executed
4.2 Daemon Thread
- If all foreground threads die, background threads will die automatically
public class DaemonThread extends Thread {
@Override
public void run() {
for(int i = 0; i< 1000; i++){
System.out.println("DaemonActivity" + i);
}
}
public static void main(String[] args){
DaemonThread thread = new DaemonThread();
thread.setDaemon(true);
thread.start();
for(int i = 0; i < 10; i ++ ){
System.out.println("MainActivity" + i);
}
}
}
4.3 thread sleep sleep
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
sleep
After the method suspends the current thread, it will give other threads a chance to execute, and ignore the priority of other threads; but theyield
method will only give threads with the same or higher prioritysleep
The method will turn into the blocking state, and will not turn into the ready state until the blocking time has passed;yield
force the current thread into the ready statesleep
The method throwsInterruptedException
, the yield method does not throw an exception
4.4 Change thread priority
- Threads with high priority get more execution opportunities, threads with low priority get fewer execution opportunities
setPriority
AndgetPriority
methods to set and return the priority of the specified thread
5. Thread synchronization
run()
Method does not have synchronization security- ***java*** introduces a synchronization monitor to solve the problem of multi-thread synchronization,
sychronized(obj)
whichobj
means sharing resources
5.1 Synchronization method
- Synchronous method is to use
synchronized
to modify a method - The default synchronization monitor for instance methods is
this
- The immutable classes in ***Java*** are always thread-safe, and mutable objects need additional methods to ensure their thread safety
public class DaemonThread extends Thread {
static int balance = 100;
int drawAmount;
String name;
public DaemonThread(int drawAmount, String name){
this.drawAmount = drawAmount;
this.name = name;
}
@Override
public void run() {
this.draw(drawAmount);
}
public synchronized void draw(int amount){
if(balance >= amount){
System.out.println(this.name + "取出了" + amount);
try{
Thread.sleep(1);
} catch (InterruptedException e){
e.printStackTrace();
}
balance -= amount;
System.out.println("\t余额为" + balance);
} else{
System.out.println(this.name + "取现失败");
}
}
public static void main(String[] args){
new DaemonThread(50, "A").start();
new DaemonThread(100, "B").start();
}
}
5.2 Release the lock of the synchronization monitor
In the following cases, the thread will release the lock on the synchronization monitor
- The synchronization method of the current thread, the synchronization code block execution ends
- Encountered break , return
- Encountered an exception
- The program executed the
wait()
method to synchronize the monitor object
Will not be released under the following circumstances:
- When executing a synchronous method, the program calls the
Thread.sleep()
Thread.yield()
method - Another thread called the thread's
suspend
method
5.3 Synchronization lock
- ***Java5*** provides a more powerful synchronization lock mechanism, which can be synchronized by explicitly defining synchronization lock objects
- Lock provides a wider range of locking operations than synchronized, and supports multiple related Condition objects
- Lock type:
Lock
ReadWriteLock
ReentrantLock : commonly used, you can relock a locked object
ReentrantReadWriteLock
StampedLock
Method name | effect |
---|---|
lock |
Lock |
unlock |
Unlock |
5.4 Deadlock
A and B, B and A
5.5 Thread communication
5.5.1 Traditional thread communication
Method name | effect |
---|---|
wait |
Cause the current thread to wait until other threads call the notify() or notifyAll() method of the synchronization monitor |
notify |
Wake up a single thread waiting in this synchronization monitor |
notifyAll |
Wake up all threads waiting in this synchronization monitor |
wait()
Must be executed with lock
5.5.2 Using Condition
- If not applicable synchronized system to ensure thread synchronization, using Lock objects to ensure synchronization, it can not be used
wait
,notify
,notifyAll()
to thread communication - When using
Lock
objects, Java providesCondition
guaranteed thread coordination Condition
Methods as below
Method name | effect |
---|---|
await |
Cause the current thread to wait until other threads call the signal() or signalAll() method of the synchronization monitor |
signal |
Wake up a single thread in this Lock object |
signalAll |
Wake up all threads in this Lock object |
5.5.3 Using a blocking queue
- ***Java*** provides a BlockingQueue interface
- When the producer thread tries to
BlockingQueue
put elements in, if the queue is full, the thread is blocked; when the consumer thread tries toBlockingQueue
take out elements, if the queue is empty, the thread is blocked
Method name | effect |
---|---|
put(E e) |
Try to put the E element intoBlockingQueue |
take() |
Try to BlockingQueue extract elements from the head of |
public class BlockingQueueThread extends Thread {
private BlockingQueue<String> bq;
public BlockingQueueThread(BlockingQueue<String> bq){
this.bq = bq;
}
@Override
public void run() {
String[] strColl = new String[]{
"Java",
"Kotlin",
"JavaScript"
};
for(int i = 0; i < 1000; i ++){
try {
System.out.println(getName() + "开始动工" + i);
bq.put(strColl[i % 3]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(getName() + "工作结束");
}
public static void main(String[] args){
BlockingQueue<String> bq = new ArrayBlockingQueue<>(5);
new BlockingQueueThread(bq).start();
}
}
As you can see, when Thread-0 runs to the 6th time, it has been blocked and cannot add content to it.
6. Thread groups and unhandled exceptions
ThreadGroup
Represents the thread group, which can classify and manage a batch of threads- The child thread is in the same thread group as the parent thread that created it
ThreadGroup
method
Method name | effect |
---|---|
int activeCount |
Returns the number of active threads in the thread group |
interrupt |
Interrupt the number of all active threads in this thread group |
isDaemon |
Whether the thread group is a background thread group |
setDaemon |
Set up background threads |
setMaxPriority |
Set the highest priority of the thread group |
7. Thread Pool
- The thread pool creates a large number of idle threads when the system starts
- The program passes an
Runnable
object orCallable
object to the thread pool, and the thread pool will start an idle thread to execute them - The thread ends without death, but returns to the idle state
- ***Java8*** added a new
Executors
factory class to produce thread pool
7.1 ThreadPool
public class ThreadPoolTest {
public static void main(String[] args){
ExecutorService pool = Executors.newFixedThreadPool(2);
java.lang.Runnable target = () -> {
for (int i = 0; i < 100 ; i ++){
System.out.println(Thread.currentThread().getName() + "的i为" +i);
}
};
pool.submit(target);
pool.submit(target);
pool.shutdown();
}
}
7.2 ForkJoinPool
- Split a task into multiple small tasks for parallel calculation, and then merge the results of multiple small tasks into a total calculation result
ForkJoinPool
YesExecutorService
implementation class
public class PrintTask extends RecursiveAction {
public static int THREADSH_HOLD = 50;
private int start;
private int end;
public PrintTask(int start, int end){
this.start = start;
this.end = end;
}
@Override
protected void compute() {
if(end - start < THREADSH_HOLD){
for(int i = start; i < end; i ++){
System.out.println(Thread.currentThread().getName() + "的i为" + i);
}
} else {
PrintTask left = new PrintTask(start, (start + end) / 2);
PrintTask right = new PrintTask((start + end) / 2 , end);
left.fork();
right.fork();
}
}
public static void main(String[] args) throws InterruptedException {
PrintTask printTask = new PrintTask(0 , 300);
ForkJoinPool pool = new ForkJoinPool();
pool.submit(printTask);
pool.awaitTermination(2, TimeUnit.SECONDS);
pool.shutdown();
}
}