Without flow control, the code is executed line by line from top to bottom. With such a mechanic, it would be difficult to use a program to fulfill the need to play a game while listening to music; Because according to the order of execution, can only be executed from the top down; Either listening to music or playing games can be performed at the same time.

In order to solve this problem, multi-threaded concurrency is introduced into the program design. The knowledge in this article is applicable to Windows, MAC, and Linux systems, but the display interface and feature names are different. The following uses Windows as an example.

Parallelism and concurrency

Parallelism and concurrency are two confusing concepts. They may not be very different in literal terms, but when interpreted in the context of computer operation, they are quite different:

  • Parallelism: the simultaneous occurrence of multiple events at the same point in time is true simultaneity;
  • Concurrency: multiple events occur at the same time in the macro, while the CPU switches back and forth on multiple events in the micro, but the switching time is fast, and can not be captured by human eyes, so in a period of time that human can observe, multiple events are happening at the same time;

Operating system operating environment, and refers to a period of time in the macro multiple programs running at the same time; In a single-CPU environment, only one program is executed by the CPU at any moment (that is, only one program gets the CPU time slice). The CPU alternates execution between multiple programs, that is, schedules the running time of each program, so as to realize the concurrent running of multiple programs.

Today, with the continuous development of computer hardware, computer are generally have more than one CPU, in such environment of multiple cpus, originally by a single processor to run these programs can be assigned to multiple CPU to run, so as to realize the true program run in parallel, in terms of macro or micro level, programs are running at the same time. In this way, the efficiency of the program will be greatly improved. PS: THE CPU time slice is the elapsed time allocated by the CPU for each program.

When buying a computer, the manufacturer advertises “several core processors,” where “core” means that the CPU has several physical cores that can handle several program calls in parallel. To find out how many cores your computer has, open Task Manager.

You can also view it through computer properties and device Manager. Therefore, a single-core processor cannot run multiple tasks in parallel, only multiple tasks can run concurrently in a single-core processor. Each task is represented by a thread. The concurrent running of multiple threads in a single processor is called thread scheduling.

At a macro level, multiple threads run in parallel; From the micro point of view, multiple threads are serial running, that is, one thread one thread running; If you don’t understand the macro and the micro here, it’s a lot easier to think of the macro as a human view of what’s going on, and the micro as a CPU view of what’s going on.

Threads and processes

Process: A process is an application that runs in memory. Each process has a separate memory space in memory. Each piece of software can start multiple processes.

Thread: A thread is a unit of control in a process, that is, each unit task in the process. A process can have multiple threads running concurrently.

Multi-process refers to multiple programs running at the same time in an operating system, and multi-threading refers to multiple tasks running at the same time in the same process. Each task running in the operating system is a process, and each task in the process is a thread; Operating system is a multi-task system, it can have multiple processes, and each process can have multiple threads.

The difference between thread and process:

  1. Each process has independent memory space, that is, the data storage space (heap, stack space) in the process is independent, and each process has at least one thread;

  2. For threads: heap memory space is shared, stack memory space is independent; Threads consume far fewer resources than processes, and threads can communicate with each other;

  3. Thread is the basic component of the process unit, so also called thread process element, or light process;

  4. Thread execution is determined by the CPU scheduler, beyond the programmer’s control;

Thread scheduling: a single CPU of a computer can only execute one computer instruction at any time, and each process can only execute relevant instructions if the CPU usage is obtained.

Multi-threaded concurrency, in fact, is running each process in turn to obtain the use of CPU to perform their respective tasks; In a multi-process environment, there will be multiple threads waiting for CPU usage, and the operation of allocating CPU usage to these waiting threads is called thread scheduling.

Thread scheduling is divided into preemptive scheduling and time-sharing scheduling.

  • Preemptive scheduling: multiple threads seize CPU resources in an instant, and whoever grabs the CPU will run, with more randomness;

  • Timesharing: allocating equal CPU time slices to multiple threads in waiting;

Preemptive scheduling is used in Java multithreading.

multithreading

Multi-threading and single-threading are just like multi-lane and single-lane. Multi-lane can be passed by multiple cars at the same time, while single-lane can only be passed by multiple cars in sequence. Multithreading has multiple threads running concurrently at the same time. A single thread only has a single thread executing multiple tasks sequentially.

If you take downloading files as an example: single thread is only one file download channel, multithreading is multiple download channels downloading files at the same time. When the server provides the download service, the download program shares the server bandwidth, with the same priority, the server allocates the bandwidth equally to all threads in the download:

Broadband bandwidth is calculated in bits, and download speed is calculated in bytes, 1 byte = 8 bits, so 1024KB/s means the Internet broadband is 1M (1024 thousand bits), and download speed needs to subtract 8 from 1024KB/s to get 128KB/s.

Multithreading is to complete multiple tasks synchronously, is to improve the efficiency of the system as a whole, but can not improve the running efficiency of the program code itself.

Advantages of multithreading: Multithreading, as a multi-task and high-concurrency operation mechanism, has its unique advantages:

  1. Processes cannot share memory space with each other, but threads can (via heap memory);

  2. When creating a process, the operating system reallocates system resources to it. And the creation of thread resources will be much smaller, in the realization of multi-task concurrency, compared with multi-process, multi-thread efficiency will be much higher;

  3. The Java language has built-in support for multithreading, not just scheduling calls to the underlying operating system; Java also has friendly support for multithreading, which greatly simplifies development costs;

Create a process

Creating a process in Java can be done in two ways:

1. Java.lang.Runtime is used as an example code:

Public static void main(String []args) throws IOException {// CMD Runtime Runtime = Runtime.geTruntime (); runtime.exec("cmd");  
}  
Copy the code

2. Implement java.lang.ProcessBuilder with the following example code:

Public static void main(String []args) throws IOException {// CMD ProcessBuilder pb = new ProcessBuilder("cmd"); 
        pb.start();  
}
Copy the code

Create a thread

Create threads by inheriting the Thread class. Note that only subclasses of Thread are Thread classes;

  1. Create a new class that inherits from java.lang.Thread;

  2. Rewrite the run method in Thread class in the new Thread subclass, write Thread logic in the run method;

  3. Create thread objects to execute thread logic;

  public  class  ExtendsThreadDemo  {  
          public  static  void  main(String  []args)  {  
                 for  (int i =  0; i <  50; i++)  {  
                         System.out.println("Main thread"  + i);  
                         if(i == 13) { NewThread newThread = new NewThread(); newThread.start(); }}}} // NewThread class NewThread extends Thread {@override public voidrun()  {  
                for  (int i =  0; i <  50; i++)  {  
                      System.out.println("New thread"+ i); }}}Copy the code

Create threads by implementing the Runnable interface. Note that the Runnable implementation class is not a Thread class, so it will start differently from the Thread subclass.

  1. Create a new class implementationjava.lang.Runnable;
  2. Override in the newly created implementation classRunnableIn the classrunMethods,runMethod to write thread logic;
  3. createThreadObject, passed inRunnableImplement class objects and execute thread logic;

Example code is as follows:

public class ImplementsRunnableDemo {
    public static void main(String []args) {
		for (int i = 0; i < 50; i++) {
			System.out.println("Main thread" + i);
			if(i == 13) { Runnable runnable = new NewRunnableImpl(); Thread thread = new Thread(runnable); thread.start(); }}}} // New thread class NewRunnableImpl implements Runnable {@override public voidrun() {
		for (int i = 0; i < 50; i++) {
			System.out.println("New thread"+ i); }}}Copy the code

Create a thread with an anonymous inner class. Create a thread with an anonymous inner class.

Public class AnonymousInnerClassDemo {public static void main(String []args) {public static void main(String []args) {for (int i = 0; i < 50; i++) {
          System.out.println("Main thread" + i);
          if (i == 13) {
            new Thread(new Runnable() {
              @Override
              public void run() {
                for (int j = 0; j < 50; j++) {
                  System.out.println("New thread"+ j); } } }).start(); }}}}Copy the code

Of course, threads can be created using the anonymous inner class of Thread, but this approach is rarely used; Example code is as follows:

Public class AnonymousInnerClassDemo {public static void main(String []args) {public static void main(String []args) {for (int i = 0; i < 50; i++) {
          System.out.println("Main thread" + i);
          if (i == 13) {
            new Thread() {
              @Override
              public void run() {
                for (int j = 0; j < 50; j++) {
                  System.out.println("New thread"+ j); } } }.start(); }}}}Copy the code

Multithreading case

Case requirements: Children’s Day, set up a balloon snatching competition program, a total of 50 balloons, three children Xiao Hong, Xiao Qiang, Xiao Ming to grab; Please use multi-threading technology to implement the above race process.

Implement the above example by inheriting the Thread class. Example code is as follows:

public class ExtendsDemo {
    public static void main(String []args) {
 
		new Student("Little red").start();
		new Student("Small strong").start();
		new Student("Xiao Ming").start();
 
    }
}

class Student extends Thread {
 
	private int num = 50;
	private String name;
	public Student(String name) {
		super(name);
		this.name = name;
	}
 
	@Override
	public void run() {
		for (int i = 0; i < 50; i++) {
			if (num > 0) {
				System.out.println(this.name + "Got it." + num + "Balloon"); num--; }}}}Copy the code

By checking the output results, I found a problem: each child grabbed 50 balloons, which was contradictory to the original 50 balloons; But don’t worry, we can use the second approach: implement the interface to solve the above case.

Two, using the implementation of the interface to achieve the above case; Example code is as follows:

public class ImplementsDemo {
    public static void main(String []args) {
        Balloon balloon = new Balloon();
        new Thread(balloon, "Little red").start();
        new Thread(balloon, "Small strong").start();
        new Thread(balloon, "Xiao Ming").start(); }} // Implements Runnable {private int num = 50; @Override public voidrun() {
		for (int i = 0; i < 50; i++) {
        if (num > 0) {
          System.out.println(Thread.currentThread().getName() + "Got it." 
                     + num + "Balloon"); num--; }}}}Copy the code

In this case we use thread.currentThread (), which returns a reference to the currently executing Thread object, so the name of the currently executing Thread object can be obtained as follows: String name = Thread.currentThread().getName(); .

By looking at the printed results of the case, it is not difficult to find that the three children grabbed 50 balloons in total, meeting the requirement of 50 balloons in total. When we look at the code in the main function, we see that the reason is that three threads share a Balloon object, which has about 50 balloons in it.

With that in mind, the problem with using the inherited Thread class is solved. Next, the above two ways to achieve multithreading are analyzed and summarized:

Using inheritanceThreadClass mode:

  1. Using inheritance to achieve multithreading in operation will be more convenient; For example: Yessuper.getName()To get the name of the current thread object directly;
  2. Due to theJavaIt’s single inheritance, so if you inheritThread, the class cannot have any other parent classes;
  3. For the case of snatching balloons, it can not solve the problem well;

Using the implementation interface:

  1. Compared to inheritance, implementation and threading are slightly more complex; For example, to obtain the current thread name, passThread.currentThread().getName();To obtain;
  2. Because of the way it’s implemented,JavaIt supports multiple implementations, so in addition toRunnableIn addition to interfaces, you can implement other interfaces and inherit from other classes;
  3. Can well achieve the case requirements: multiple threads share a resource;

The end, although the old man is not serious, but the old man a talent! Follow me for more programming basics.