Multithreading
- Process is an ordered collection of instructions and data. It has no running meaning and is a static concept. Process is an execution process of executing program. It is a dynamic concept and the unit of system resource allocation.
- Usually, a process can contain several threads. Of course, there is at least one thread in a process, otherwise it has no meaning. Thread is the unit of CPU scheduling and execution.
- Threads are independent execution paths; When the program is running, even if it does not create its own thread, there will be multiple threads in the background, such as main thread, gc thread (garbage collection thread), etc;
- main() is called the main thread, which is the entry of the system and is used to execute the whole program; In a process, if multiple threads are opened up, the operation of threads is scheduled by the scheduler. The scheduler is closely related to the operating system, and the sequence can not be interfered by human beings.
- When operating on the same resource, there will be a problem of resource grabbing, and concurrency control needs to be added;
- Threads will bring additional overhead, such as cpu scheduling time and concurrency control overhead; Each thread interacts in its own working memory. Improper memory control will cause data inconsistency.
- Difference between normal call and multithreaded call:
When calling the run() method in normal calls, it will be executed in sequence, and when calling the start() method in multi-threaded calls, it will be called alternately. Due to the fast speed of the computer, it can be regarded as simultaneous.
Thread creation
- Multithreading is mainly created by inheriting the Thread class, implementing the Runnable interface and implementing the Callable interface. Inheriting the Thread class and implementing the Runnable interface are commonly used and belong to the basic operations that everyone should be proficient in.
1, Inherit Thread class
- Custom Thread class inherits Thread class;
- Rewrite the run() method and write the thread execution body;
- Create a thread object and call the start() method to start the thread.
//Create Thread method 1: inherit the Thread class, override the run () method, and call start to start the Thread public class Test1 extends Thread { @Override public void run() { //Thread body of run method for (int i = 0; i < 200; i++) { System.out.println("I'm looking at the code--"+i); } } public static void main(String[] args) { //Main thread, creating thread object Test1 test1 = new Test1(); //Call start() to start the thread test1.start(); for (int i = 0; i < 500; i++) { System.out.println("I'm learning multithreading--"+i); } } }
2, Implement runnable interface
- Define the MyRunnable class to implement the Runnable interface;
- Implement the run() method and write the thread execution body;
- Create a thread object and call the start() method to start the thread.
- Recommended: it avoids the limitation of single inheritance, is flexible and convenient, and is convenient for the same object to be used by multiple threads.
//Create thread method 2: implement the runnable interface and rewrite the run method. The execution thread needs to drop into the runnable interface implementation class and call the start method public class Test2 implements Runnable{ @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("I'm looking at the code--"+i); } } public static void main(String[] args) { //Create an implementation class object for the runnable interface Test2 test2 = new Test2(); //Create a thread object and start the created thread through the thread object (agent) //Thread thread = new Thread(test2); //thread.start(); Anonymous Inner Class new Thread(test2).start(); for (int i = 0; i < 500; i++) { System.out.println("I'm learning multithreading--"+i); } } }
- Problems caused by runnable interface:
Concurrency problems occur when multiple threads manipulate an object at the same time: when multiple threads operate the same resource, the thread is unsafe and data disorder will occur. A data is obtained by multiple threads.
Example: when three threads operate on train ticket inventory at the same time, one data is used many times, resulting in data disorder.
//In the example of buying a train ticket, an error occurred in operating the same object data public class Test3 implements Runnable{ private int ticketNums = 10; @Override public void run() { while (true){ if (ticketNums<=0){ break; } System.out.println(Thread.currentThread().getName()+"--Got the second"+ticketNums--+"Ticket"); } } public static void main(String[] args) { Test3 test3 = new Test3(); new Thread(test3,"1 number").start(); new Thread(test3,"2 number").start(); new Thread(test3,"3 number").start(); } }
3, Implement the callable interface
- To implement the Callable interface, the return value type is required
- When overriding the call method, you need to throw an exception
- Create target object
- Create execution service: ExecutorService ser = Executors.newFixedThreadPool(1);
- Submit execution: Future result1 = ser.submit(t1);
- Get result: boolean r1 = result1.get()
- Shut down the service: ser.shutdownNow();
package Demo01; import java.util.concurrent.*; public class TestCallable implements Callable<Boolean> { private String url; //Network picture saving address private String name; //Saved file name public TestCallable(String url,String name){ this.url = url; this.name = name; } @Override public Boolean call(){ //A download method WebDownloader webDownloader = new WebDownloader(); webDownloader.downloader(url,name); System.out.println("The downloaded file name is:"+name); return true; } public static void main(String[] args) throws ExecutionException,InterruptedException{ TestCallable t1 = new TestCallable("url","name"); TestCallable t2 = new TestCallable("url","name"); TestCallable t3 = new TestCallable("url","name"); //Create execution service ExecutorService ser = Executors.newFixedThreadPool(3); //Submit for execution Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); //Get results boolean rs1 = r1.get(); boolean rs2 = r2.get(); boolean rs3 = r3.get(); //Shut down service ser.shutdownNow(); } }