Multithreading (on)

Multithreading

1. Processes and threads

1. Process

    The execution cycle of a program in an operating system is called a process. Each process contains at least one thread.

2. Thread

The execution unit in a process that is responsible for program execution. The thread itself depends on the program to run, and the thread is the sequential flow of control in the program.

Compared with a process, a thread is more "lightweight", and creating and canceling a thread is much less expensive than starting a new process; there is no thread without a process, and once a process is terminated, the threads within it no longer exist.

3. Single thread

The program contains only one thread, and the main method is actually a main thread.

4. Multithreading

Running multiple tasks in one program is to make better use of resources.

5, the state of the thread


Second, the realization of multi-threading

1. Inherit the Thread class

Thread is defined in the Java.lang package, and the run() method must be overridden when inheriting Thread .

(1) Create a thread

//Thread body class
class MyThread extends Thread{
	private static int num = 0;
	public MyThread(int num) {
		num++;
	}
	//All threads start executing from here
	public void run() {
		System.out.println("actively created "+num+" thread");
	}
}

(2) Create a thread object to start a thread

Wrong way to start multithreading:

   In the case of a thread, it is natural to generate an instantiated object of the thread class and then call its run() method. In fact, we can't directly call the run() method, the call of the run () method will only make sequential printing, which has nothing to do with multi-threading.

public class MoreThread4_25 {
	public static void main(String[] args) {
		Thread mThread1 = new MyThread("First thread");
		Thread mThread2 = new MyThread("Second thread");
		Thread mThread3 = new MyThread("third thread");
		mThread1.run();
		mThread2.run();
		mThread3.run();
	}
}

           

The correct way to start multithreading:

      In fact, we should use the start() method in the Thread class to start the thread.

Because public synchronized void start() this method will automatically call the thread's run() method.

public class MoreThread4_25 {
	public static void main(String[] args) {
		Thread mThread1 = new MyThread("First thread");
		Thread mThread2 = new MyThread("Second thread");
		Thread mThread3 = new MyThread("third thread");
		mThread1.start();
		mThread2.start();
		mThread3.start();
	}
}

Repeated execution will find that all thread objects are executed alternately

                                 

(3) The difference between the start() method and the run() method call

class MyThread extends Thread{
	private String info;
	public MyThread(String info) {
		this.info = info;
	}
	//All threads start executing from here
	public void run() {
		System.out.println("The ID of the actively created child thread \""+info+"\": "+Thread.currentThread().getId());
	}
}
public class MoreThread4_25 {
	public static void main(String[] args) {
		System.out.println("主线程ID:"+Thread.currentThread().getId());
		Thread mThread1 = new MyThread("First thread");
                Thread mThread2 = new MyThread("Second thread");
                //The correct way to start multi-threading
                mThread1.start();
                // wrong multithreading start
                mThread2.run();
	}
}

        

As can be seen from the output of the above figure:

The thread IDs of Thread1 and Thread2 are different, and the IDs of Thread2 and the main thread are the same. At this time, it indicates that the creation of the run() method does not create a new thread, but runs the run() method in the main thread, which has nothing to do with ordinary methods. the difference.

The start() method of Thread1 is called before the run() method of Thread2 , but the result of the operation is to output the ID of the run() method of Thread2 first , indicating that the newly created thread will not affect the subsequent execution of the main thread.

2. The Runnable() interface implements multithreading

In addition to inheriting the Thread class (with the limitation of single inheritance), creating a thread in Java can also achieve similar functions by implementing the Runnable() interface, but also override the run() method.

( 1 ) Implement the Runnable interface

class MyRunnable implements Runnable{
	private String info;
	public MyRunnable(String info) {
		this.info = info;
	}
	@Override
	public void run() {
		System.out.println("新建线程名:"+this.info+",ID:"+Thread.currentThread().getId());
	}
	
}
public class MoreThread4_25{
	public static void main(String[] args) {
		System.out.println("主线程ID:"+Thread.currentThread().getId());
		MyRunnable myRunnable = new MyRunnable("线程1");
		//And at this time, the MyThRunnable class is no longer inherited from the Thread class and implements the Runnable interface
		//Although the limitation of single inheritance is solved, no start() method is inherited.
		//Then you need to use the constructor provided by the Thread class at this time.
		Thread thread = new Thread(myRunnable);
		thread.start();
	}
}

                        

Implementing multithreading by implementing the Runnable interface is actually:

   We define a subtask and give it to Thread to execute.

   This way of implementing multi-threading must use Runnable as the parameter of Thread . It is still to use the start() method of the Thread class to create a new thread and complete the subsequent work. Similar to Thread , if you directly call its run() method, it is no different from ordinary methods. , and does not create a new thread.

( 2 ) Inner class and Lambda expression implementation of Runnable interface object

/*
 * Runnable interface object anonymous inner class, Lambda expression implementation
 * */
public class MoreThread4_25{
	public static void main(String[] args) {
		System.out.println("主线程ID:"+Thread.currentThread().getId());
		//Inner class implements Runnable interface object
		new Thread(new Runnable() {
			private String info = "Thread 1";
			@Override
			public void run() {
				System.out.println("新建线程名:"+this.info+",ID:"+Thread.currentThread().getId());
			}
		}).start();
		//The Lambda expression implements the interface object of Runnable
		Runnable runnable = () ->{
			String info = "Thread 2";
			System.out.println("New thread name: "+info+", ID: "+Thread.currentThread().getId());
		};
		new Thread(runnable).start();
	}
}

                       

3. The difference between Thread and Runnable

The Runnable interface is better than the Thread class to implement multi-threading, because it avoids the limitation of single inheritance. The Thread class is a subclass of the Runnable interface, so the Thread class must override the run () method of Runnable . And the multi-threaded program class implemented by Runnable can better describe the concept of program sharing.

The Inheritance Structure of Thread Classes: The Proxy Design Pattern

                      

(1) Use the Thread class to achieve data sharing

class MyThread extends Thread{
	private int ticketNum = 5;
	public void run() {
		while(this.ticketNum > 0) {
			System.out.println("Remaining votes: "+this.ticketNum--);
		}
	}
}
public class MoreThread4_25{
	public static void main(String[] args) {
		new MyThread().start();
		new MyThread().start();
		new MyThread().start();
	}
}

                         

According to the results, it can be found that three threads are started, each processing their own data but not jointly processing the same set of data.

To achieve common processing of the same set of data, ticketNum should be set as a static variable.

(2) Use Runnable to achieve data sharing

class MyRunnable implements Runnable{
	private int ticketNum = 5;
	public void run() {
		while(this.ticketNum > 0) {
			System.out.println("Remaining votes: "+this.ticketNum--);
		}
	}
}
public class MoreThread4_25{
	public static void main(String[] args) {
		MyRunnable myRunnable = new MyRunnable();
		new Thread(myRunnable).start();
		new Thread(myRunnable).start();
		new Thread(myRunnable).start();
	}

}

                        

 The multi-threaded program class implemented by Runnable can better describe the concept of program sharing


4. Callable implements multithreading

A new development package has been added since JDK1.5 : java.uti.concurrent . This development kit is mainly used for high-concurrency programming, and contains many classes that will be used in high-concurrency operations. A new interface Callable is defined in this package .

The run() method in Runnable has no return value, and its design also follows the design principle of the main method: don't look back when the thread starts. But in many cases, some return values ​​are required. For example, some threads may bring some return results after the execution is completed. In this case, only Callable can be used to realize multi-threading.

class MyCallable implements Callable<String>{
	private int ticketNum = 5;
	public String call() throws Exception {
		while(this.ticketNum > 0) {
			System.out.println("Remaining votes: "+this.ticketNum--);	
		}
		return "Sorry, I just don't have a ticket";
	}
}
public class MoreThread4_25{
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		FutureTask<String> task = new FutureTask<>(new MyCallable());
		new Thread(task).start();
		new Thread(task).start();
		System.out.println(task.get());
	}
}
                        

 
 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326069159&siteId=291194637