Write in front: I haven't studied very seriously these two days. This article is sorted out according to the dark horse video on station b. There are still many imperfections. I'll look at the teacher's video screen for detailed sorting after a while
8.13. I started to write notes again and watched the video twice. It's really good
1. How does Java implement multitasking
java is multithreaded to achieve multitasking!!!
There is no multi process and co process programming in java!!!!
2.java multithreading programming
|-- inherit Thread class |-- realization Runable Interface |-- Callable and Future Interface( jdk1.5) |-- Thread pool( jdk1.5)
3. Inherit Thread class method 1: inherit Thread class
- Define a class MyThread to inherit the Thread class
- Override the run() method in the MyThread class
- Create an object of the MyThread class
- Start thread
Two small problems:
- Why override the run() method?
- Because run() is used to encapsulate the code executed by the thread
- What is the difference between the run() method and the start() method?
- run(): encapsulates the code executed by the thread. It is called directly, which is equivalent to the call of ordinary methods
- start(): start the thread; The run() method of this thread is then called by the JVM
package com.study_01; public class MyThread extends Thread{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(i); } } }
package com.study_01; public class MyThreadDemo { public static void main(String[] args) { MyThread my1 = new MyThread(); MyThread my2 = new MyThread(); // my1.run(); // my2.run(); // void start() causes this thread to start execution; The Java virtual machine calls the run method of this thread. my1.start(); my2.start(); } }
4. Implement the interface of Runable
Method 2: implement Runnable interface
- Define a class MyRunnable to implement the Runnable interface
- Override the run() method in the MyRunnable class
- Create an object of the MyRunnable class
- Create an object of Thread class and take the MyRunnable object as the parameter of the construction method
- Start thread
There are two implementation schemes of multithreading
- Inherit Thread class
- Implement Runnable interface
Advantages of implementing the Runnable interface over inheriting the Thread class
- It avoids the limitation of Java single inheritance
- It is suitable for multiple codes of the same program to deal with the same resource, and effectively separates the thread from the program code and data, which better reflects the object-oriented design idea
package com.study_05; public class MyRunnable implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); } } }
package com.study_05; public class MyRunnableDemo { public static void main(String[] args) { // Create an object of the MyRunnable class MyRunnable my = new MyRunnable(); // Create an object of Thread class and take the MyRunnable object as the parameter of the construction method // Thread(Runnable target) assigns a new thread object. // Thread t1 = new Thread(my); // Thread t2 = new Thread(my); // Thread(Runnable target, String name) Thread t1 = new Thread(my,"high-speed rail"); Thread t2 = new Thread(my,"aircraft"); //Start thread t1.start(); t2.start(); } }
5.Callable and Future interfaces (jdk1.5)
The juc package is 5.0
Callable and Future interfaces
The Callable interface needs a generic type, which refers to the type of result to be returned after the thread method is executed;
TaskFuture implementation class in the Future interface
This implementation class has implemented the Future and Runable interfaces
package com.study.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class TestThread03 { public static void main(String[] args) { // Create a Callable thread object MyThread03 mt = new MyThread03(); // FutureTask object FutureTask<String> future = new FutureTask<String>(mt); // The current thread was started new Thread(future, "call_thread").start(); for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() +"The main thread is running"+ i); } // Note: use the get method to get the return value after the thread runs // This method is called after all threads are started try { System.out.println("After the child thread runs, the result is:" + future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } class MyThread03 implements Callable<String> { @Override public String call() throws Exception { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":"+i); } return "The return value after the thread runs"; } }
6. Some common methods of Thread objects
Some common methods of Thread objects: start() # Start thread run() # This method cannot be manually executed. It is a thread method. It is executed by the start method. The JVM bottom layer automatically executes this method setName(name) # Set thread name getName() # Get thread name getId() # Get thread number getPriority() # Gets the priority of the thread interrupt(); isAlive() # Determine whether the thread is alive isDaemon() # Determine whether the thread is a daemon thread setDaemon(true); # Set the current thread as a daemon join(); # Block the main thread and let the sub thread run after it is completed Thread.sleep(millisecond) # Static method. If the current thread sleeps, whether to lock it or not Thread.yield() # Letting the current thread give up once will not release the lock
seven ✨ What is the difference between inheriting Thread and implementing Runable interface?
inherit Thread Class, multiple thread objects cannot share member variables!!! If it is a static member, it is also shared!!!! realization Runable Interfaces are sub thread classes, and multiple thread objects share the member variables of thread classes!!!
8. Synchronous lock
There are three ways to write 1,Put it on the method: the whole method is synchronous If all code in a method may have thread safety problems, it is recommended to synchronized Write directly on the method if synchronized Write it on the method, which is the lock 2,Synchronization block: put the code that may be thread safe in a synchronization block key It is an object. Any object can be used. It is generally recommended to use it this Keywords act as synchronized (key) { // Thread safety issues may occur count++; } 3,Static method: it's special. Let's say it alone The static method adds synchronized Keyword, because the static method belongs to a class, the class (essentially the bytecode file of the class) acts as a lock.
Class content starts on August 9
👀date8.9—
9.Lock lock
Although we can understand the lock object problem of synchronization code blocks and synchronization methods, we do not directly see where the lock is added and where the lock is released for clearer expression
How to add and release locks? JDK5 provides a new Lock object Lock
The Lock implementation provides a wider range of locking operations than using synchronized methods and statements
Lock provides methods for obtaining and releasing locks
- void lock(): get lock
- void unlock(): release the lock
Lock is an interface that cannot be instantiated directly. Its implementation class ReentrantLock is used to instantiate it here
Construction method of ReentrantLock
- Reentrantlock(): create an instance of ReentrantLock
package com.study_11; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SellTicket implements Runnable { private int tickets = 100; private Lock lock = new ReentrantLock(); @Override public void run() { while (true) { try { lock.lock(); if (tickets > 0) { // Simulate the ticket selling time through the Sleep() method class try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "The second is being sold" + tickets + "Ticket"); tickets--; } } finally { lock.unlock(); } } } }
package com.study_11; public class SellTicketDemo { public static void main(String[] args) { // Create an object of SellTicket class SellTicket st = new SellTicket(); // Create three Thread class objects, take the SellTicket object as the parameter of the construction method, and give the corresponding window name Thread t1 = new Thread(st,"Window 1"); Thread t2 = new Thread(st,"Window 2"); Thread t3 = new Thread(st,"Window 3"); // Start thread t1.start(); t2.start(); t3.start(); } }
10. Synchronized lock upgrade
jdk7.0 synchronized Major changes have been made: synchronized Applying for locks directly to the operating system consumes too much resources and is too heavy. Oracle Modifications were carried out: 1,Unlocked state (bias lock) 2,The lock will be upgraded from bias lock to spin lock( CAS) CAS(compare and swap): Compare and exchange Spin locks can easily cause: ABA problem 3,Spin lock upgraded to heavyweight lock
CAS And optimistic lock and pessimistic lock: The concept of optimistic locking: the task thread will never cause concurrency problems Pessimistic lock: as long as concurrency occurs, thread safety problems will arise Pessimistic lock: it solves the concurrency problem, but it is inefficient Optimistic lock: add a version number to the data without locking. Whenever the value changes, add 1 to the version number. Finally, judge whether it is concurrent by comparing the versions
11.volatile keyword
High concurrency: visibility, ordering, atomicity In the case of multithreading, each thread has an execution stack independently. Each thread has independent useful data, and the memory is invisible to each other stay java In, volatile Keywords have two core functions: 1,Variables modified by it can break the memory barrier in multithreading, that is, variables modified by it have visibility. 2,Prohibit instruction reordering!!!
12. Use of synchronized in singleton mode
gof 23 Medium design mode: |-- Decorator design mode |-- Singleton design pattern The construction method must be privatized. |-- Hungry Han style Create objects directly on attributes, static,Directly by the memory, the program does not exit, and the memory is not released This is very good. There is no thread safety problem. The only defect is that the memory will be occupied and will not be released whether it is used or not |-- Lazy style When you need to use objects, you can create objects again, which solves the hungry man's memory occupation problem. Lazy is not directly used in multithreading because it is non thread safe. If you want to solve thread safety problems,Locking is required: |-- Lock the method directly,Thread safety is solved directly,But the efficiency is not high(The range of the lock is too large) |-- Lock the code that creates the object(The range of the lock is small and the efficiency is high) |-- If you write this way, you need to judge it twice
13. Thread life cycle
fourteen ✨ deadlock
Deadlock( dead lock): In the case of multithreading, the thread safety problem is solved by locking. Deadlock: be sure to avoid it!!! It causes a lot of data waste and can not solve the problem at the same time. Deadlock avoidance: an excellent solution: banker algorithm There are four necessary conditions for deadlock formation: |-- mutex |-- Request hold |-- Loop waiting |-- Inalienable conditions Deadlock is a waste of resources. In normal programming, deadlock must be avoided
👀date8.11—
15. Use of atomic classes
java.util.concurrent.atomic The classes under this package are atomic!!! Operator: Self addition // i++ ==> t = i+1; i = t; Self subtraction += // i += 3 ==> t = i + 3; i = t; -= Without atomicity, thread safety problems will occur in the case of multithreading AtomicInteger All methods of these classes are atomic methods implemented using spin locks
16.ThreadLocal
The thread object provides a copy object, which is characterized in that each thread owns it independently ThreadLocal object Multithreading is generally preferred ThreadLocal,In the case of multithreading, save the value to ThreadLocal In, multithreads have their own values and will not fight set() // Add values in your own thread get() // Gets the value stored in ThreadLocal in its own thread remove() // Finally, be sure to remove the value!!!, Otherwise, it is prone to memory overflow
17. Object reference of Java
Strong reference: Object o = new Object(); o It is a strong reference and will not be used gc Recycle, even when calling System.gc(); // o = null; |-- Atomicity: java.util.concurrent.atomic Class based on atomicity under package AtomicInteger AtomicLong AtomicBoolean |-- ThreadLocal object Private object per thread get() set() remove() Thread Precautions for use |-- ThreadLocal Underlying source code |-- java of object reference |-- Strong reference |-- Soft reference |-- Weak reference |-- Virtual reference
18. Producer and consumer models
Producer consumer model
Producer consumer model is a very classic multi-threaded cooperation model. Understanding the producer consumer problem can make us have a deeper understanding of multi-threaded programming
In fact, there are two types of threads:
- One is the producer thread used to produce data
- One is consumer thread, which is used to consume data
In order to decouple the relationship between producers and consumers, shared data areas are usually used, just like a warehouse
- The producer's production data is directly placed in the shared data area, and does not need to care about the behavior of consumers
- Consumers only need to obtain data from the shared data area, and do not need to care about the behavior of producers
In order to reflect the wait and wake-up during production and consumption, Java provides several methods for us to use. These methods are the wait and wake-up methods of Object class in Objec class:
Producer consumer case
package com.study_12; public class Box { // Define milk quantity private int milk; // Define a member variable to represent the status of the milk box private boolean state = false; // Provides the operation of storing milk public synchronized void put(int milk) { // If there is milk, wait for consumption if (state) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // If not, produce milk this.milk = milk; System.out.println("The milkman will"+this.milk+"Put a bottle of milk into the milk box"); // After production, modify the milk box status state = true; // awaken notifyAll(); } public synchronized void get() { // If not, wait for production if(!state) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // Consume if you have System.out.println("The user gets the second"+this.milk+"Bottle milk"); state = false; // awaken notifyAll(); } }
package com.study_12; public class Customer implements Runnable{ private Box b; public Customer(Box b) { this.b = b; } @Override public void run() { while (true){ b.get(); } } }
package com.study_12; public class Producer implements Runnable{ private Box b; public Producer(Box b) { this.b = b; } @Override public void run() { for (int i = 1; i <= 5; i++) { b.put(i); } } }
package com.study_12; public class BoxDemo { public static void main(String[] args) { // Create a milk box formation, which is a shared data area Box b = new Box(); // Create a producer object and pass the milk box object as a constructor parameter, because the operation to store milk is called in this class Producer p = new Producer(b); // Create a consumer object and pass the milk box object as a constructor parameter, because the operation to store milk is called in this class Customer c = new Customer(b); // Create two thread objects Thread t1 = new Thread(p); Thread t2 = new Thread(c); // Start thread t1.start(); t2.start(); } }
19. Thread pool
Thread pool: Pool mode: create a large number of objects we need in advance and put them in a pool (concept), The object is created in advance and does not need to be destroyed, so it is more efficient Advantages: it is more efficient and avoids repeated creation and destruction of objects Disadvantages: the memory occupation is high, and the number of pools is difficult to control Controlling the number of pools is the most critical issue java Thread pool is 1.5 provide juc In the package, the underlying implementation is actually Callable and Future Interface |-- Depending on the situation, we create thread pools for many different scenarios
20. Use of several common containers under high and fat
Use of several common containers under high parallel distribution ArrayList Vector LinkedList HashMap HashSet Hashtable ...... It is emphasized that thread safety exists in all containers |-- Thread safe: Vector: Added lock, benefit: no thread safety problem, disadvantage: poor efficiency |-- juc Package: |-- ConrrentHashMap |-- CopyOnWriteArrayList |-- CopyOnWriteArraySet |-- ConrrentHashMap 1,Thread safety 2,Read write separation