Program, process, thread

  • Program: A set of instructions written in a language to accomplish a specific task, a static piece of code.
  • Process: a running process of a program, or a running program. Processes are the basic unit of resource allocation.
  • Thread: A thread, further refined by a process, is an execution path within a program. A thread is a unit of scheduling and execution, each thread has a separate run stack and program counter, and thread overhead is minimal.

Thread life cycle

Common methods in the Thread class

  • Start () : Starts the current thread; Calls run() of the current thread.
  • Run () : It is common to override this method in the Thread class to declare the operations to be performed by the created Thread.
  • CurrentThread () : Static method that returns the thread executing the current code.
  • GetName () : Gets the name of the current thread.
  • SetName () : Sets the name of the current thread.
  • Yield () : Releases the execution of the current CPU.
  • Join () : thread A calls thread B’s join() method, and thread A enters the blocking state. Thread A does not end the blocking state until thread B completes.
  • Sleep (Long Millitime) : Allows the current thread to “sleep” the specified Millitime millisecond. The current thread is blocked for the specified Millitime millisecond.
  • IsAlive () : checks whether the current thread isAlive.
  • GetPriority () : Gets the priority of the thread.
  • SetPriority (int p) : Sets the priority of the thread.
  • A thread has three priorities: MAX_PRIORITY: 10; MIN _PRIORITY: 1; NORM_PRIORITY: 5.

A way to create multiple threads

Thread class inheritance

Steps:

  • Create a subclass that extends from Thread.
  • Overrides the run() method of the Thread class to declare operations performed by the next Thread in the run() method.
  • Create a subclass object of Thread.
  • Call start() with this object.

Example: Three Windows selling tickets (thread safety issues)

class MThread extends Thread{ private static int tickets = 100; @override public void run() {while(true){if(tickets > 0){system.out.println (getName() + "+ tickets--"); }else{ break; } } } } public class ThreadTest { public static void main(String[] args) { MThread t1 = new MThread (); MThread t2 = new MThread (); MThread t3 = new MThread (); T1. Elegantly-named setName (" window 1 "); T2. Elegantly-named setName (" window 2 "); 3 t3. Elegantly-named setName (" window "); t1.start(); t2.start(); t3.start(); }}Copy the code

Description: Limited to single inheritance of classes.

Implement the Runnable interface

Steps:

  • Create a class that implements the Runnable interface.
  • The implementation class implements the abstract method in Runnable: run().
  • Create an object that implements the class.
  • Pass this object as an argument to the constructor of The Thread class to create an object of the Thread class.
  • Call start() from an object of the Thread class.

Example: Three Windows selling tickets (thread safety issues)

class MThread implements Runnable{ private int tickets = 100; @override public void run() {while(true){if(tickets > 0){system.out.println (thread.currentThread ().getName() +" Tickets: "+ tickets--); }else{ break; } } } } public class ThreadTest { public static void main(String[] args) { MThread m = new MThread(); Thread t1 = new Thread(m); Thread t2 = new Thread(m); Thread t3 = new Thread(m); T1. Elegantly-named setName (" window 1 "); T2. Elegantly-named setName (" window 2 "); 3 t3. Elegantly-named setName (" window "); t1.start(); t2.start(); t3.start(); }}Copy the code

Description: not limited to the single inheritance of the class; Suitable for handling situations where multiple threads share data.

Implement Callable interface

Steps:

  • Create an implementation class that implements Callable.
  • Implement the call method to declare the actions this thread needs to perform in call().
  • Create an object for the Callable interface implementation class.
  • The object of the FutureTask is created by passing the object of this Callable interface implementation class as a parameter to the FutureTask constructor.
  • Pass the object of FutureTask as an argument to the constructor of the Thread class, create the Thread object, and call start().

Example: Iterate over even numbers up to 100 and calculate their sum

class MThread implements Callable{ @Override public Object call() throws Exception { int sum = 0; for (int i = 2; i < 101; i+=2) { System.out.println(i); sum += i; } } return sum; } } public class ThreadTest { public static void main(String[] args) { MThread thread = new MThread (); FutureTask futureTask = new FutureTask(thread); new Thread(futureTask).start(); The return value of try {//get() is the return value of call() implemented by the FutureTask constructor parameter Callable. Object sum = futureTask.get(); System.out.println(" sum: "+ sum); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); }}}Copy the code

Note: The call() method returns a value and can throw an exception; Callable supports generics.

The thread pool

Steps:

  • Provides a thread pool with a specified number of threads.
  • Performs operations for the specified thread. You need to provide objects that implement the Runnable or Callable interface implementation classes.
  • Close the thread pool.

Example: Two threads traversing odd and even numbers within 100

class NumberThread implements Runnable{ @Override public void run() { for(int i = 1; i < 101; i+=2){ System.out.println(Thread.currentThread().getName() + ": " + i); } } } class NumberThread1 implements Runnable{ @Override public void run() { for(int i = 2; i < 101; i+=2){ System.out.println(Thread.currentThread().getName() + ": " + i); } } } public class ThreadPool { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); ThreadPoolExecutor service1 = (ThreadPoolExecutor) service; service.execute(new NumberThread()); Runnable service.execute(new NumberThread1()); //service. Submit (Callable Callable); // use Callable service.shutdown(); }}Copy the code

Improved response speed; Reduce resource consumption; Easy thread management.

Thread synchronization mechanism

Address thread safety issues

Synchronized code block

Synchronized {// Code that needs to be synchronized} example: three Windows selling tickets

class Windows extends Thread{ private static int tickets = 100; @Override public void run() { while(true){ synchronized(Windows.class){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if(tickets > 0){system.out.println (getName() + "+ tickets--); }else{ break; } } } } } public class Test { public static void main(String[] args) { Windows t1 = new Windows(); Windows t2 = new Windows(); Windows t3 = new Windows(); T1. Elegantly-named setName (" window 1 "); T2. Elegantly-named setName (" window 2 "); 3 t3. Elegantly-named setName (" window "); t1.start(); t2.start(); t3.start(); }}Copy the code

Synchronized methods

Place synchronized in the declaration of a method. Example: Three Windows selling tickets.

class Windows implements Runnable { private int tickets = 100; @Override public void run() { while(true){ show(); } } private synchronized void show(){ if(tickets > 0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } system.out.println (thread.currentThread ().getName() + "; } } } public class Test{ public static void main(String[] args) { Windows t = new Windows(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); T1. Elegantly-named setName (" window 1 "); T2. Elegantly-named setName (" window 2 "); 3 t3. Elegantly-named setName (" window "); t1.start(); t2.start(); t3.start(); }}Copy the code

Lock

class A{ private final ReentrantLock lock = new ReentrantLock(); public void m(){ lock.lock(); Try {// thread-safe code} finally{lock.unlock(); }}}Copy the code

Example: Three Windows selling tickets

class Window implements Runnable{ private int ticket = 100; private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while(true){ try{ lock.lock(); if(ticket > 0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } system.out.println (thread.currentThread ().getName()); } }finally { lock.unlock(); } } } } public class LockTest { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); T1. Elegantly-named setName (" thread 1 "); T2. Elegantly-named setName (" thread 2 "); T3. Elegantly-named setName (" thread 3 "); t1.start(); t2.start(); t3.start(); }}Copy the code

Synchronized vs. lock:

  • Lock is a display lock, manually opened and closed; Synchronized is an implicit lock that is automatically released out of scope.
  • Lock only code block locks; Synchronized has code block locks and method locks.
  • With lock locks, the JVM takes less time to schedule threads and performs better; And it has better scalability.

Thread communication

Three methods

  • Wait (): Once this method is executed, the current thread blocks and releases the synchronization monitor.
  • ) notify(): Once this method is executed, one of the threads being waited is woken up. If more than one thread is waited, the one with the highest priority is awakened.
  • NotifyAll (): Once this method is executed, all threads being waited are awakened.

instructions

  • Wait (), notify(), and notifyAll() must be used in synchronized code blocks or synchronized methods.
  • The callers of wait(), notify(), and notifyAll() must be synchronized blocks or synchronization monitors in synchronized methods. Otherwise, there will be a IllegalMonitorStateException anomalies.
  • Wait (), notify(), and notifyAll() are defined in the java.lang.object class.

Example: producer-consumer problem

class Clerk{ private int productCount = 0; public synchronized void produceProduct(){ if(productCount < 20){ productCount ++; System.out.println(thread.currentThread ().getName() + "productCount" + "productCount "); notify(); }else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void consumeProduct() { if(productCount > 0){ System.out.println(thread.currentThread ().getName() + "productCount" + "productCount "); productCount --; notify(); }else { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Productor extends Thread{ private Clerk clerk; public Productor(Clerk clerk) { this.clerk = clerk; } @override public void run() {system.out.println (" string "+ thread.currentThread ().getName() +" string "); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.produceProduct(); } } } class Consumer extends Thread{ private Clerk clerk; public Consumer(Clerk clerk) { this.clerk = clerk; } @override public void run() {system.out.println (" "+ thread.currentThread ().getName() +" "); while(true){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } clerk.consumeProduct(); } } } public class ProductTest { public static void main(String[] args) { Clerk clerk = new Clerk(); Productor p1 = new Productor(clerk); P1.setname (" producer 1"); Consumer c1 = new Consumer(clerk); C1.setname (" consumer 1"); p1.start(); c1.start(); }}Copy the code

The last

At the end of the article the author sorted out a lot of information for you! Including Java core knowledge + a full set of architect learning materials and video + first-line factory interview treasure dictionary + resume template interview ali Meituannetease Tencent Xiaomi IQiyi Quick hand bilibili bilibili interview questions +Spring source code collection +Java architecture actual combat e-books and so on!

All free to share with you, welcome to pay attention to the public number: the future has light to receive!