catalogue
2, Creation and use of threads
1. By inheriting the Thread class
2. By implementing the Runnable interface:
3. Related methods in Thread class
1, Concept
1. Program, process, thread
Program: a set of instructions written in a language to complete a task, and refers to a piece of static code.
Process: it is an execution process of a program, or it can be a running program. It is a dynamic process with its own process of generation, operation and extinction ---------- that is, the life cycle.
Thread: the process can be further subdivided into threads. When the program is running, it is an internal execution path. If a program executes multiple paths in parallel, it is multithreading.
As the unit of scheduling and execution, threads have independent running stacks and program technicians. Multiple threads in a process share the same memory unit and memory address space, allocate objects from the same heap and access the same objects and variables. However, multiple threads operate on shared variables and objects, which will bring security risks
2, Creation and use of threads
1. By inheriting the Thread class
Steps:
① : create a subclass of Thread
② : override the run() method in the Thrad class and declare the operation of executing this thread in the run() method
③ : instantiates the object of the current subclass
④ : call the start method in the Thread class
//Create Thread subclass class MyThread extends Thread { //Override the run method in the Thread class public void run() { //Declare the operation performed by this thread in the run method for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.print(Thread.currentThread().getName() + ":" + i);//Output the thread name and i of the current thread } } } } public class ThreadTest12 { public static void main(String[] args) { //An object that creates a subclass of Thread MyThread mt = new MyThread(); //Call the start method: 1. Start the current thread; 2. Call the run () method of the current thread mt.start(); } }
There are two problems with this approach:
① We cannot start the thread by directly calling the run() method
② . start another thread. The thread that has already executed the start() method cannot be allowed to execute it. Otherwise, an error will be reported:
IllegalThreadStateException
2. By implementing the Runnable interface:
Steps:
① : create a class that implements the Runnable interface
② : override the abstract method in the Runnable class: run()
③ : create an object that implements this class
④ : pass the object of this implementation class as a parameter to the constructor of Thread class to create the object of Thread class
⑤ : call the start method in the Thread class
class MyThread implements Runnable { public void run() { //Declare the operation performed by this thread in the run method for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.print(Thread.currentThread().getName() + ":" + i);//Output the thread name and i of the current thread } } } } public class ThreadTest { public static void main(String[] args) { //Create an object that implements the class MyThread mt = new MyThread(); //Pass the object of this implementation class as a parameter to the thread construct, where the object of thread class is created Thread ta = new Thread(mt);//It reflects polymorphism //Call the start () method in the Thread class ta.start(); Thread ta1 = new Thread(mt);//It reflects polymorphism ta1.start();//Start another thread and execute the run method. Note: at this time, two threads operate on the same object } }
Summary: compare the two thread creation methods:
1. Priority in development: the way to implement Runnable interface
reason:
① : the implementation method has no limitation of class inheritance
② : the implementation method is more suitable for dealing with the situation that multithreading has shared data
Exercise between the two:
① : the Thread class itself also implements the run method in the Runnable interface
② : you need to override the run method
③ : all operations that the thread needs to perform must be declared in the run method
3. Related methods in Thread class
void start(): starts the thread and executes the run() method of the object
run(): the operation that the thread is scheduled to execute again
String getName(): returns the name of the current object
void setName(String name): sets the name of the current thread
static Thread currentThread(): returns the current Thread, which is this in the Thread subclass. It is usually used for the main Thread and Runnable implementation classes
static void yield(): thread concessions, pauses the thread currently executing, and gives execution opportunities to threads with the same or higher priority
If there are no threads with the same priority in the queue, this method is ignored
join(): when the join method of another thread is invoked in a program execution stream, the calling thread will be blocked until the join method joined by the join method is executed.
Static void sleep (long millis):
① : enable the current active thread to give up control over the cpu within the specified time, so that other threads have the opportunity to be executed, and queue up again when the time is up
② : throw InterruptedException exception
stop(): force the end of the thread declaration cycle. It is not recommended
boolean isAlive: determines whether the thread is still alive
4. Thread priority
Threads with the same priority form a first in first out queue (first in first out service) and use the time slice strategy
For priority threads, the preemptive strategy of priority scheduling is adopted (high priority threads preempt CPU)
Priority level of thread:
MAX_PRIORITY: 10
MIN_PRIORITY: 1
NORM_PRIORITY: 5
Relevant methods involved:
getPriority() returns the priority registration of the related thread
setPriority (int newPriority) sets the priority registration of related threads
Note:
When a thread is created, it inherits the priority of the parent thread
For low priority, the probability of scheduling is low, not necessarily after the completion of high priority
3, Thread life cycle
1. Several states of threads
4, Thread synchronization
Preamble: when a thread is executing but has not completed the operation, The participation of other threads will lead to thread safety problems, which can be solved in the following two ways (idea: when a thread is operating shared data, let other threads not participate in it until thread a completes its operation, so that even if thread a is blocked, it cannot be changed)
1. Synchronous code block
Synchronized (synchronized monitor){ // Synchronization monitor: commonly known as lock. An object of any class can be called a lock. Multiple threads must share a lock!
//Code to be synchronized
}
① : combine synchronous code blocks by inheriting Thread subclasses
//Create Thread subclass class MyThread extends Thread { //Override the run method in the Thread class public void run() { synchroinzed(this){ //You can use the current object, but use this carefully in inheriting the Thread class //Declare the operation performed by this thread in the run method for (int i = 0; i < 100; i++) { if (i % 2 == 0) { System.out.print(Thread.currentThread().getName() + ":" + i);//Output the thread name and i of the current thread } } } } } public class ThreadTest12 { public static void main(String[] args) { //An object that creates a subclass of Thread MyThread mt = new MyThread(); //Call the start method: 1. Start the current thread; 2. Call the run () method of the current thread mt.start(); } }
② : the method of implementing Runnable interface is combined with synchronous code block
class Window1 implements Runnable{ private int ticket = 100; Object obj = new Object(); @Override public void run() { while (true){ synchronized(this) { //You can also use the current object. this: the only object of window1 if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":" + ticket); ticket--; } else { break; } } } } } public class WindowTest1 { public static void main(String[] args) { Window1 w = new Window1(); Thread t =new Thread(w); Thread t1 =new Thread(w); Thread t2=new Thread(w); t.start(); t1.start(); t2.start(); } }
2. Synchronization method
① : the synchronization method is combined by implementing the Runnable interface
//Using synchronization method to solve the thread safety problem of implementing Runnable interface class Window3 implements Runnable { private int ticket = 1000; @Override public void run() { while (true) { show(); } } public synchronized void show() { //Sync monitor: this // synchronized (this) { if (ticket > 0) { /* try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); }*/ System.out.println(Thread.currentThread().getName() + ":" + ticket); ticket--; } // } } } public class WindowTest3 { public static void main(String[] args) { Window3 w = new Window3(); Thread t = new Thread(w); Thread t1 = new Thread(w); Thread t2 = new Thread(w); t.start(); t1.start(); t2.start(); } }
② : combine synchronization methods by inheriting Thread class
/**Using synchronous methods to deal with Thread safety problems in the way of inheriting Thread class * * Summary of synchronization methods: * 1,The synchronization method still involves the synchronization monitor, but we don't need to declare it explicitly * 2,Non static synchronization method. The synchronization monitor is this * Static synchronization method: the synchronization monitor is the current class itself * */ class Window4 extends Thread { private static int ticket = 100; //Become unique, use static @Override public void run() { while (true) { show(); } } private static synchronized void show() {//Synchronization monitor: Window.class //private synchronized void show() / / this method is wrong. Three objects come in if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "Ticket No.:" + ticket); ticket--; } } } public class WindowTest4 { public static void main(String[] args) { Window4 w = new Window4(); Window4 w1 = new Window4(); Window4 w2 = new Window4(); w.setName("Window 1"); w1.setName("Window 2"); w2.setName("Window 3"); w.start(); w1.start(); w2.start(); } }