This is the 31st day of my participation in the August More Text Challenge
1. Procedures, processes, threads
1.1 the program
A set of instructions written in a language to accomplish a specific task, a static piece of code
1.2 process
It is an execution of a program, or a running program, a dynamic process
Create – exist – Die
1.3 the thread
Is part of the process, is an execution path within the program
Each thread has its own run stack and program counter
Process is the basic unit of program running and resource allocation.
Threads are the basic unit of CPU scheduling and dispatch that can operate independently.
Parallel, concurrent
- Parallel: Multiple cpus perform multiple tasks at the same time. For example: more than one person at a time
- Concurrency: a CPU executes multiple tasks simultaneously (using a time slice mechanism), operating on the same resource. For example: second kill, more than one person to do the same thing
2, the Thread
Thread creation 1:
Inherit Thread and override the run() method.
- Cannot be called directly
run()
Method to start a thread, which simply calls a class’s normal method;- We can’t let it happen again
start()
The thread is called againstart()
Method, an exception will be reportedIllegalThreadStateException
.
2.1 Common Methods of Thread
The method name | Methods effect |
---|---|
void start() | The thread starts execution, and the Java virtual machine calls the thread’s run method |
void run() | The execution content of the thread |
String getName() | Returns the name of this thread |
void setName(String name) | Set the name of this thread to parameter name |
int getPriority() | Returns the priority of this thread |
void setPriority(int newPriority) | Change the thread priority |
static Thread currentThread() | Returns a reference to the thread object currently executing. |
static void sleep(long millis) | Causes the currently executing thread to pause (temporarily stop execution) for the specified number of milliseconds. |
void yield() | The current thread releases execution from the CPU (and may continue immediately) Performed) |
void join() | Thread B.jiin () is called in thread A and thread A is blocked Thread A does not stop blocking until thread B has finished executing |
Void stop() (deprecated) | The stop line |
2.2 Thread scheduling
2.2.1 Scheduling Policies
Time slice: preemptive, preemption of CPU execution according to thread priority, higher priority is easier to obtain; Same priority thread, first in first out queue.
2.2.2 Priority level
- MAX_PRIORITY:10
- MIN_PRIORITY:1
- NORM_PRIORITY:5 (default)
Usage:
- Void setPriority(int priority) : sets the thread priority
- Int getPriority() : gets the thread priority
Then pay attention to
- Thread creation inherits its parent thread priority;
- A low priority is simply a low probability of getting a CPU schedule, and is not necessarily called after a high priority thread.
2.3 Classification of threads
- Daemon thread: serves the user thread (main thread), such as Java garbage collection;
- If the JVM is full of daemons, the current JVM exits.
- User thread (main thread)
- in
start()
Pre-method callthread.setDaemon(true)
You can turn a user thread into a daemon thread.
- in
3. Synchronization mechanism of threads
1. Synchronize code blocks
synchronized(Synchronization monitor){// Code that needs to be synchronized: statements that threads operate on shared data
}
Copy the code
- Code that operates on shared data is code that needs to be synchronized (no more code, no less code);
- Shared data: variables that multiple threads operate on in common;
- Synchronization monitor, commonly known as
The lock
. An object of any class can act as a lock;But multiple threads must share the same lock; - Thread inherits the class, commonly used
The name of the current class.class
As a synchronization monitor; - Runnable interface implementation class, you can consider using
this
Act as synchronization monitor
2. Synchronization method
If the code that operates on shared data is fully declared in a method, you can use the declaration to synchronize the entire method
- The synchronization method is still designed to the synchronization monitor, but we don’t need to declare it explicitly;
- Non-static synchronization methods, synchronization monitors are:
this
; - Static synchronization methods, synchronization monitors are:
The current class itself
;
3, the Lock locks
java.util.concurrent.locks.lock
Implementation class:
Already,
ReentrantReadWriteLock ReaLock,
ReentrantReadWriteLock.WriteLock
-
Starting with JDK 5.0, Java provides a more powerful thread synchronization mechanism by explicitly defining a synchronization lock object. A synchronous Lock uses the Lock object to act as a Lock;
-
Java. Util. Concurrent. The locks. Lock interface is the tool of control multiple threads to Shared resources access;
A Lock provides independent access to a shared resource. Only one thread can Lock the Lock object at a time. The thread must acquire the Lock object before accessing the shared resource.
-
The ReentrantLock class implements Lock, which has the same concurrency and memory semantics as Synchronized. In implementing thread-safe control, ReentrantLock is commonly used, which can explicitly Lock and release the Lock.
implementation
- Start synchronization: lock();
- End synchronization: unlock().
ReentrantLock
Fair lock: first come, last served
Unfair lock: You can jump the queue (default)
4. Advantages and disadvantages of threads
- The synchronization method solves the safety problem of the thread. — > benefits
- When manipulating synchronized code, only one thread can participate, while the other threads wait. It’s a single-threaded process, which is inefficient. — > limitations
4. Thread communication
Wait () : Once this method is executed, the current thread blocks and releases the synchronization monitor;
Notify () : This method wakes up one of the threads being waited, or one of the threads being waited with the highest priority.
NotifyAll () : Once this method is executed, all threads being waited are awakened.
Description:
-
Wait (), notify(), and notifyAll() must be used in synchronized code blocks or synchronized methods.
-
The callers of wait(), notify(), and notifyAll() must be synchronized blocks or synchronization monitors in synchronized methods.
Otherwise, there will be a IllegalMonitorStateException anomalies
Producer/consumer issues
The Productor gives the product to the Clerk, and the Customre takes it from the Clerk, who can only hold a fixed number of products at a time (e.g. 20), if the producer view produces more products, the clerk will ask the producer to stop for a while, and notify the producer to continue production if there is room for more products in the store; If there is no product in the store, the clerk will tell the consumer to wait, if there is a product in the store to inform the consumer to pick up the product.
They are both producers.
// Producer: controls product objects
class Producer extends Thread{
private Product product;
public Producer(a){}public Producer(Product product){
this.product = product;
}
// Make a product
public void run(a){
System.out.println("Production products ================");
// Call the product method to produce
while(true) {try {
Thread.sleep(10);
} catch(InterruptedException e) { e.printStackTrace(); } product.production(); }}}Copy the code
A Consumer
// Consumer: controls product objects
class Consumer extends Thread{
private Product product;
public Consumer(a){}public Consumer(Product product){
this.product = product;
}
// Buy the product
public void run(a){
System.out.println("Buy products ================");
// Call the product method to sell
while(true) {try {
Thread.sleep(100);
} catch(InterruptedException e) { e.printStackTrace(); } product.sell(); }}}Copy the code
Product (Product)
/ / product
class Product{
private int productCount = 0;
private Object sync = new Object();
// Make a product
public synchronized void production(a){
if(productCount < 20){
productCount++;
System.out.println(Thread.currentThread().getName() + "-- Production control" + productCount + "Piece of merchandise");
notify();
} else{
System.out.println(Thread.currentThread().getName() + "-- If number of products > 20, wait() to execute");
try {
wait();
} catch(InterruptedException e) { e.printStackTrace(); }}}/ / sell
public synchronized void sell(a){
if(productCount > 0){
System.out.println(Thread.currentThread().getName() + "*** purchased the no." + productCount + "Piece of merchandise");
productCount--;
notify();
} else{
System.out.println(Thread.currentThread().getName() + "-- No more items, wait() to execute");
try {
wait();
} catch(InterruptedException e) { e.printStackTrace(); }}}}Copy the code
To start (producing, consuming) :
public class ProductTest {
public static void main(String[] args) {
Product product = new Product();
/ / production line
Producer producer = new Producer(product);
producer.setName("Producer");
// Consume line 1
Consumer consumer1 = new Consumer(product);
consumer1.setName("Consumer 1");
// Consume line 2
Consumer consumer2 = new Consumer(product);
consumer2.setName("Consumer 2"); producer.start(); consumer1.start(); consumer2.start(); }}Copy the code
Create thread-3: Implement the Callable interface
Create thread in JDK 5.0
- implementation
Callable
Interface;- Using thread pools
Callable is more powerful than Runnable
- Compared with the
run()
Method, which can have a return value;- Method can throw an exception;
- Support for generic return values;
- Need to use
FutureTask
Class, such as getting the return result
The Future interface
- Can be specific to
Runnable
,Callable
Cancel the execution result of the task, query whether the task is completed, and obtain the result. FutureTask
isFuture
The unique implementation class of the interface;FutureTak
At the same timeRunnable
,Future
Interface, which can be used as bothRunnable
North county execution, and can serve asFuture
getCallable
The return value of the
Implementation steps
-
Create an implementation class that implements the Callable interface and implements generics, the return value type of the Call () method;
-
Implement the call() method to declare the operations this thread needs to perform in call();
// create a generic class that implements the Callable interface class NumThread implements Callable<Integer>{ @Override public Integer call(a) throws Exception { System.out.println(Thread.currentThread().getName() + "Execution -- -- -- -- --"); int sum = 0; for(int i = 0; i < 100; i++){ if(i % 2= =0){ sum += i; }}returnsum; }}Copy the code
-
Create an object for the Callable interface implementation class.
-
The object of the FutureTask is created by passing the object of the Callable interface implementation class as a parameter to the FutureTask constructor.
-
Pass the object of FutureTask as an argument to the constructor of the Thread class, create the Thread object, and call the start() method.
-
Gets the return value of the Call () method in the Callable interface implementation class.
public class Callable_Test { public static void main(String[] args) { // 3. Create an object for the 'Callable' interface implementation class; NumThread numThread = new NumThread(); // 4. Pass the object of the 'Callable' interface implementation class as a parameter to the 'FutureTask' constructor to create the object of 'FutureTask'; FutureTask<Integer> futureTask = new FutureTask<Integer>(numThread); // 5. Pass the 'FutureTask' object as an argument to the 'Thread' constructor, create the 'Thread' object and call the 'start()' method. Thread thread = new Thread(futureTask); thread.start(); try { // 6. Get the return value of the call() method in the Callable interface implementation class. Integer sum = futureTask.get(); System.out.println(sum); } catch (InterruptedException e) { e.printStackTrace(); } catch(ExecutionException e) { e.printStackTrace(); }}}Copy the code
Create thread-4: Use a thread pool
Background: Heavily used resources that are frequently created and destroyed, such as threads in the case of concurrency, can have a big impact;
Create multiple threads in the terraced field and put them into the thread pool. It can avoid frequent creation and destruction and realize reuse.
Benefits:
Increased speed (reduced time to create new threads);
Reduce resource consumption (reusing threads from the thread pool, not creating them every time);
Easy thread management
The relevant API
JDK 5.0 provides thread pool-related apis: ExecutorService interface, Executors tools
- ExecutorService: True thread pool interface, common subclasses
ThreadPoolExecutor
- Void execute(Runnable command) : Executes a task or command. No return value is returned
Runnable
; - Future Submit (Callable Task) : Performs a task, returns a value, and is generally used for execution
Callable
- Void shutdown() : shuts down the connection pool
- Void execute(Runnable command) : Executes a task or command. No return value is returned
- Executors: Factory classes for tools and thread pools, used to create and return different types of thread pools
- Executors. NewCachedThreadPool () : create a according to the need to create a new thread’s thread pool, but when available will use structure before thread;
- Executors. NewFixedThreadPool (int nThreads) : create a reusable fixed number of threads thread pool;
- Executors. NewSingleThreadExecutor () : create a use of unbounded queue run a single worker threads to perform a task;
- Executors. NewScheduledThreadPool (int corePoolSize) : create a thread pool, can run for scheduling command after the given delay, or run on a regular basis
Implementation steps
public class Executors_Test {
public static void main(String[] args) {
// Provide the thread pool for the specified number of threads. // Return the ThreadPoolExecutor class according to the Executors tool
ThreadPoolExecutor --> inherits AbstractExecutorService --> implements ExecutorService
ThreadPoolExecutor service = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
The ThreadPoolExecutor class can use more methods to manage thread pools. Such as:
service.setCorePoolSize(20);
// service.setKeepAliveTime(long time,TimeUnit unit);
// service.setMaximumPoolSize(30);
// service.setRejectedExecutionHandler(RejectedExecutionHandler handler);
// service.setThreadFactory(ThreadFactory factory);
// 2. To perform the specified thread operation, you need to provide the implementation class of the Runnable interface or the Callable interface
System.out.println(service.getClass());
// 2.1 Implement classes using the Runnable interface
service.execute(new Number_Runnable());
// 2.2 Implements the class using the Callable interface and returns a value
Future<Integer> future = service.submit(new Number_Callable());
try {
int sum = future.get();
System.out.println("Callable implementation class gets return value" + sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 3. Close the connection poolservice.shutdown(); }}/ / implementation Runnable
class Number_Runnable implements Runnable{
@Override
public void run(a) {
int sum = 0;
for (int i = 0; i < 100; i++){
if(i % 2= =0){
System.out.println(Thread.currentThread().getName() + "--" + i);
sum += i;
}
}
System.out.println("Runnable-- the even sum up to 100 is:"+ sum); }}// Implement Callable and use generics to control the return value type
class Number_Callable implements Callable<Integer> {
@Override
public Integer call(a) throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++){
if(i % 2= =1){
System.out.println(Thread.currentThread().getName() + "--"+ i); sum += i; }}returnsum; }}Copy the code
The interview questions
1. The difference between synchronized and Lock
- Same: Both address thread-safety issues
- Not the same:
synchronized
Is the built-in Java keyword;Lock
Is a Java class;synchronized
The mechanism automatically releases the lock after executing the corresponding synchronized code block.Lock
Manual synchronization is required (lock()
), and termination of synchronization also requires manual implementation (unlock()
).synchronized
Reentrant lock, can not break, unfair;Lock
Reentrant lock, determinable lock, not fair (can be set yourself)- Reentrant lock: if the thread acquires the lock from the outer method, the inner method of the thread will automatically acquire the lock (provided that the lock object is the same object or class). The lock will not block because it has been acquired before and has not been released.
- Priority order: Lock –> synchronize code block (already in method body, allocated resources) –> synchronize method (outside method body)
2,sleep()
withwait()
The difference between
sleep()
Methods belong to the Thread class; whilewait()
Method, belongs to the Object class;sleep()
Methods can be called anywhere else;wait()
Can only be called in synchronized code blocks;sleep()
Method causes a program to pause execution for a specified time, freeing the CPU for another thread, but its monitoring state remains and automatically resumes when the specified time is up. So when you callsleep()
In the process of the method,The thread does not release the object lock;- call
wait()
When it comes to methods,The thread gives up the object lock, into the pool of wait locks waiting for this thread, only called for this objectnotify()
ornotifyAll()
Method before the thread enters the object lock pool to obtain the object lock and enter the running state.Pay attention to: After awakening, will be inwait()
Continue to execute.