Concurrent Programming Basics Notes (1)

1. Thread

        When it comes to threads, everyone must be familiar with them. A thread is an entity in a process. The thread itself does not exist independently. A process is a running activity of code on a data set. It is the basic unit of system resource allocation and scheduling. A thread is an execution Path, a process has at least one thread, and multiple threads in a process share the resources of the process.

        When the operating system allocates resources, it allocates resources to processes, but cpu resources are special. They are allocated to threads, so it is threads that actually occupy cpu resources and run, so threads are also the basic unit of cpu allocation.

        In java, when we start the main method, we actually start a JVM process, and the thread where the main function is located is the main thread in this process.

        After talking so much nonsense, it is still not as easy to understand as a picture.

                                                                                                   The picture is not very good

        Known from the figure, we can see that there are multiple threads in a process, and multiple threads share the method area and heap resources of the process and threads, but each thread has its own independent program counter and stack. The question is again, what are the program counter and stack, and the heap and method area?

1.1 Program Counter (Notepad)

The program counter is actually a memory area used to record the address of the thread execution instruction recorded by         the current thread . So why is the program counter private? As mentioned above, the thread is special and the most basic unit of CPU execution, and the CPU generally uses the time slice rotation method to allow the thread to poll. Therefore, after the current thread CPU time slice is used up, the CPU must be given up and wait for the next turn. Execute it when you execute it yourself. So how do you know where this thread is executing? In fact, the program counter records the address that the thread executes when it relinquishes the CPU . When it is reassigned to the time slice, the thread can continue to execute from the address specified by its own private counter.

1.2 stack (deep secret)

       Each thread has its own stack resource, which is used to store local variables and reference addresses of custom objects . These local variables, these local variables are private to the thread and cannot be accessed by other threads; Threadlocal will be introduced later. wonderful. In addition, the stack is also used to store the stack frame (thread call record) of the thread call .

1.3 heap (home of real object, this object is not that object)

        The heap is the largest piece of memory in a process. The heap is shared by all threads in the process and is allocated when the process is created. The heap object mainly stores real instances of new custom objects .

1.4 Method area (the home of the compiled class)

        The method area is used to store information such as classes loaded by the JVM, constant pools, and static variables. It is also shared by threads. Here I want to explain that JAVA jdk places different things in the method area of ​​different versions.

1.6: Runtime constant pool, class metadata information, static variables, code compiled by the compiler, etc.

1.7: The storage is basically the same as 1.6, except that the constant pool is taken out and not stored in the method area.

2. JAVA thread creation and operation

        There are three thread creation methods in java, which are the run method that implements the Runnable interface, integrates the Thread class and rewrites the run method, and uses the FutureTask method ( with return value ).

2.1 Implement the Runnable interface

public class ThreadTest {

	public static class RunnableTask implements Runnable {
		@Override
		public void run() {
			System.out.println("implements Runnable Thread");
		}
		
	}
	public static void main(String[] args) {
		RunnableTask runnableTask =new RunnableTask();
		new Thread(runnableTask).start();
	}
}

2.2 Inheriting the Thread class

public static class ThreadTask extends Thread{
		
		@Override
		public void run() {
			System.out.println("extends Thread");
		}
	}
	
	public static void main(String[] args) {
		ThreadTask threadTask =new ThreadTask();
		threadTask.start();
	}

2.3 Implement the Callable interface

//创建一个CallableTask 实现Callable接口中的run方法
public static class CallableTask implements Callable<String>{

		@Override
		public String call() throws Exception {
			return "callable ruturn";
		}
	}
	public static void main(String[] args) {
		//FutureTask构造函数传入一个CallableTask实例
		FutureTask<String> futureTask=new FutureTask<String>(new CallableTask());
		new Thread(futureTask).start();
		try {
			//等待任务执行完成,获取返回值
			String result = futureTask.get();
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

The above described codes have their own advantages and disadvantages. For example, java only supports single inheritance, and there is no return value when implementing Runnable and inheriting the Thread class. The first two implementations cannot get back the task return result, but FutureTask can.

To be continued. . .

Reference Book: The Beauty of JAVA Concurrent Programming - Zhai Lianxue Bintian

Guess you like

Origin blog.csdn.net/m0_37506254/article/details/121323596