Multithreading Foundation

@Yixian loves potatoes

1. Process

  • Each process has its own independent memory space and system resources
  • (running program)
    cpu time slice: refers to system resources and memory space

2. Thread

  • It is an execution line in the process Each thread performs a task
  • Thread is the basic scheduling unit of CPU

3. Relationship between process and thread

  • A process can have one or more threads
  • A thread always belongs to only one process
  • Multiple threads in a process compete for resources

4. Implement threads

  • There are three ways to implement threads. The first two are commonly used, and they are basically not used in the third week

4.1: inherit Thread to implement Thread

eg:/**
 * Thread subclass
 * @author sx
 * @version 1.0 2020 October 28
 */
public class MyThread extends Thread{
	/**
	 * Override the task method in the parent class
	 */
	@Override
	public void run() {
		for (int i = 1; i <= 10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}

public static void main(String[] args) {
		//Create child thread object
		MyThread t1=new MyThread();
		MyThread t2=new MyThread();
		
		//Start thread
		t1.start();
		t2.start();
	}

4.2: implementation of Runnable interface

eg:/**
 * Task class
 * @author sx
 * @version 1.0 2020 October 28
 */
public class MyRunnable implements Runnable{
	/**
	 * Override the task method in the parent interface
	 */
	@Override
	public void run() {
		for (int i = 1; i <=10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
		  }

		public static void main(String[] args) {
		//Create task object
		MyRunnable m1=new MyRunnable();
		MyRunnable m2=new MyRunnable();
		
		//Create thread object
		Thread t1=new Thread(m1);
		Thread t2=new Thread(m2);
		
		//Start thread
		t1.start();
		t2.start();
	}

4.3: implementation method of Callable interface thread

  • I see. I don't need it now

5. Implement multithreading by inheriting Thread VS and implementing Runnable interface

5.1: code simplicity

  • Inheriting Thread to realize Thread code is more concise;
  • The implementation of Runnable interface is more complex than multithreading

5.2: Scalability

  • Thread is implemented by inheriting thread. This class can not inherit other classes, but can only implement other interfaces, with poor scalability;
  • This class can also inherit other classes and implement other interfaces, so it has good expansibility

5.3: resource sharing

  • Inherit the Thread method to realize multiple threads. If these multiple threads want to execute the same task, the task must be static to realize sharing, but static consumes resources, so the sharing is not good
  • Multiple threads are implemented by implementing the Runnable interface. If these multiple threads want to execute the same task, they only need to pass the same task object to these multiple threads, so it has good sharing

6. Name the thread:

6.1: each thread has a default name

6.2: name the thread with the construction method

eg:/**
 * Thread subclass
 * @author sx
 * @version 1.0 2020 October 28
 */
public class MyThread extends Thread{
	/**
	 * Parameter structure, name the thread
	 * @param string
	 */
	public MyThread(String name) {
		super(name);
	}

	/**
	 * Override the task method in the parent class
	 */
	@Override
	public void run() {
		for (int i = 1; i <= 10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}
}

6.3: the thread subclass declares an attribute specially used to store the thread name

6.4: calling thread object setName("name")

7. Thread hibernation

  • Let the current thread relinquish resources, stop robbing resources, pause for a specified time, and re participate in the robbing of resources when the time is up
  • Syntax: thread Sleep (milliseconds); Or thread object name Sleep (milliseconds);
eg:public static void main(String[] args) throws InterruptedException {
		for (int i = 6; i >=1; i--) {
			System.out.println(i);
			Thread.sleep(1000);
		}
	}

8. Thread priority

  • The higher the thread priority, the higher the probability of preempting resources, and it may not be able to preempt; The lower the thread priority, the lower the probability of preempting resources, but it is not necessarily impossible
  • Note: the thread priority must be set before the thread starts
  • Syntax: thread object name setPriority(int newPriority);
eg:public static void main(String[] args) {
		//Create thread object
		MyThread t1=new MyThread();
		MyThread t2=new MyThread();
		//Name the thread
		t1.setName("thread  A");
		t2.setName("thread  B");
		
		//Set thread priority
		t1.setPriority(Thread.MIN_PRIORITY);
		t2.setPriority(Thread.MAX_PRIORITY);
		
		//Start thread
		t1.start();
		t2.start();
	}

9. Thread merging

  • Merge multiple threads into one thread. The merged thread executes first, and then executes the rest of the original thread
  • Syntax: thread object name join();

9.1: merge sub threads into the main thread: the merged sub threads run first, and then run the rest of the main thread

eg:public static void main(String[] args) throws InterruptedException {
		//Create child thread object
		Thread t1=new Thread(new Runnable() {
			/**
			 * Override the task method in the parent interface
			 */
			@Override
			public void run() {
				for (int i = 1; i <=100; i++) {
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}, "thread  A");
		
		//Start child thread object
		t1.start();
		
		for (int i = 1; i <=100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
			//When the main thread runs 10, let child thread A merge
			if (i==10) {
				t1.join();
			}
		}
	}

9.2: merge sub thread A into sub thread B: run the merged sub thread A first, and then run the rest of sub thread B

eg:public class MyThread extends Thread{
	//Declare a thread object with properties
	public MyThread t;
	
	/**
	 * Task method
	 */
	@Override
	public void run() {
		for (int i = 1; i <=100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
			//When sub thread B runs 10, let sub thread A merge
			if (i==10&&Thread.currentThread().getName().equals("thread  B")) {
				try {
					//this refers to the thread B object
					this.t.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

public static void main(String[] args) throws InterruptedException {
		//Create thread object
		MyThread tA=new MyThread();
		MyThread tB=new MyThread();
		//Name the thread
		tA.setName("thread  A");
		tB.setName("thread  B");
		
		//Assign A value to the attribute of the object and let thread A be an attribute of thread B object
		tB.t=tA;
		tA.t=null;
		
		//Start thread
		tA.start();
		tB.start();
	}

10. Thread comity: let the current thread give up resources and grab again

  • Syntax: thread yield(); Or thread object yield();
eg:public static void main(String[] args) {
		//Create thread object
		Thread ta=new Thread(new Runnable() {
			/**
			 * Override the task method in the parent interface
			 */
			@Override
			public void run() {
				for (int i = 1; i <=100; i++) {
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}, "thread  A");
		
		//Start thread
		ta.start();
		
		for (int i = 1; i <=100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
			//The main thread gives way every time it runs
			Thread.yield();
		}
	}

11. Thread interrupt

11.1: interrupt method

  • interrupt() changes the interrupt state of the thread,
  • isInterrupted() determines whether the state of the thread is interrupted
eg:public static void main(String[] args) throws InterruptedException {
		//Create thread object
		Thread ta=new Thread(new Runnable() {
			/**
			 * Override the task method in the parent interface
			 */
			@Override
			public void run() {
				for (int i = 1; i <=100; i++) {
					//Judge whether the current thread interrupt status is true
					if (Thread.currentThread().isInterrupted()==true) {
						break;
					}
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}, "thread  A");
		
		//Start thread
		ta.start();
		
		for (int i = 1; i <=100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
			//When the main thread runs 10, the execution of sub thread A is interrupted
			if (i==10) {
				//Change the current interrupt state of the child thread
				ta.interrupt();
				//The main thread sleeps and gives up the resources, so that the interrupt of the child thread will take effect
				Thread.sleep(2000);
			}
		}
	}

11.2: mark with a variable whether the thread needs to be interrupted

eg:public class InterruptTest2 {
	//Declare a variable to mark whether the child thread is interrupted. It is not interrupted by default
	static	boolean flag=false;

	public static void main(String[] args) throws InterruptedException {
		//Create thread object
		Thread ta=new Thread(new Runnable() {
			/**
			 * Override the task method in the parent interface
			 */
			@Override
			public void run() {
				for (int i = 1; i <=100; i++) {
					//Judge whether the current thread interrupt flag is true
					if (flag) {
						break;
					}
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}, "thread  A");
		
		//Start thread
		ta.start();
		
		for (int i = 1; i <=100; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
			//When the main thread runs 10, the execution of sub thread A is interrupted
			if (i==10) {
				//Change interrupt flag
				flag=true;
				//Let the mainline sleep, so that the sub thread can grab the resources and run effectively
				Thread.sleep(1000);
			}
		}
	}
}

12. Daemon thread (background thread, wizard thread)

  • Daemon thread guards all non daemon threads. When all non daemon threads in a process die, the daemon thread automatically dies
  • Note: when setting a thread as a daemon thread, it must be set before starting the thread
  • Syntax: thread object setDaemon(true);
eg:public static void main(String[] args) {
		//Create thread object
		Thread t1=new Thread(new Runnable() {
			/**
			 * Override the task method in the parent interface
			 */
			@Override
			public void run() {
				for (int i = 1; i <=1000; i++) {
					System.out.println(Thread.currentThread().getName()+":"+i);
				}
			}
		}, "Daemon thread");
		
		//Set child thread as daemon thread
		t1.setDaemon(true);
		
		//Start thread
		t1.start();
		
		for (int i = 1; i <=10; i++) {
			System.out.println(Thread.currentThread().getName()+":"+i);
		}
	}

13. Thread life cycle: (interview classic)

13.1: initial state (new state)

  • When a thread object is newly created, the thread object is in its initial state

13.2: ready status

  • When a thread object calls start(), or a thread that blocks (sleep(),wait()), it is ready

13.3: operation status

  • When the ready thread grabs the cpu time slice and calls run(), the thread is running

13.4: blocking status

*When a thread calls sleep() or wait(), the thread is blocked

13.5: termination status (death status)

  • When a thread can no longer execute (the task is completed or interrupted), the thread is equal to the termination state

Summary:
1. Understand HashTable and Properties
2. Summary of the collection (key points)
3. Definition and classification of anomalies
4. Exception handling mechanism (try catch finally and throws) (emphasis)
5. Custom exception
6. Definitions and differences between processes and threads (key points)
7. Two ways to implement threads (key points)
8. Name the thread
9. Implement multithreading by inheriting Thread VS Runnable interface (key)
10. The third way to implement threads (understand)
Sleep thread (11. Focus)
12. Thread priority (understand)
13. Thread merging (key)
14. Thread comity (understand)
15. Thread interrupt (key)
16. Daemon thread
17. Thread life cycle (key)
18. Thread pool (key)

Keywords: Multithreading

Added by x_filed2k on Mon, 31 Jan 2022 15:03:07 +0200