Java beginner's notes in Silicon Valley - multithreading

Java beginner's notes in Silicon Valley - multithreading

Multithreading understanding

Understanding: compare a program to a high-speed toll station, then a toll window is a thread, and multiple windows are multi threads.
Key points:

  • Each thread has a separate stack and a program counter (pc).
  • Multiple threads share a heap
  • Each thread is performed independently

Creation and use of threads

  • Create Thread 1 (not recommended): write a subclass to inherit Thread and override the run() method
public class MyThread extends Thread{
    @Override
    public void run() {//Override the run() method
        for (int i = 0; i < 5; i++)
            System.out.println(Thread.currentThread().getName() + ":" + i);
    }
}
  • Using thread 1: call the start() method
public class Test {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();//A second thread is created here
        t1.start();
        t2.start();
    }
}

Operation results:

  • Create thread 2 (recommended): write a class that implements the Runable interface, override the run() method, and construct a thread object with the object of this class as a parameter. Thread objects with the same parameters share the same heap area.
class MyThread implements Runnable{
    int i = 10;
    @Override
    public void run() {//Override the run() method
        while(i > 0) {
            System.out.println(Thread.currentThread().getName() + ":" + i--);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread m = new MyThread();
        Thread t1 = new Thread(m);
        t1.start();
    }
}
  • You can also directly create and execute a thread in the form of an anonymous class:
new Thread(){
            @Override
            public void run() {
                //sentence
            }
        }.start();

Common methods in Thread class

Method nameeffect
getName()Returns the name of the current thread
setName()Sets the name of the current thread
currentThread()Returns the current thread (static method)
yeild()After calling a.yeild in a thread, CPU chooses another thread to execute.
join()After calling b.join in a thread, a blocks, and B executes to a after execution.
sleep(x)Current thread blocking x milliseconds (static method)
isAlive()Returns whether the current thread is alive

thread priority

  • Threads have priority. When CPU switches threads, it is more likely to switch to threads with high priority.
  • Priority is int type 1 < = value of priority < = 10
  • Thread defines three (static int) values
identifier value
MAX_PRIORITY10
NORM_PRIORITY5
MIN_PRIORITY1
  • Priority related methods
methodeffect
getPriority()Returns the priority of the thread
setPriority(x)Set priority to x

Thread life cycle

Thread safety problem solving

Multiple threads may cause thread safety problems when operating shared data. Solutions:

  • 1. synchronized keyword solution
synchronized (obj) {//obj is a lock and can be any object
 		//Code block for manipulating shared data
}

Principle: multiple code blocks locked by the same lock can only be executed after one is executed
The method of Runnable implements multithreading, and the general lock is this
The method of inheriting Thread implements multithreaded lock, which is generally the subclass name class

    1. Using the method with synchronized keyword (not recommended), the method declared as synchronized is equivalent to adding the default lock - class name to the whole function class
public synchronized void method(){

}
    1. JDK5. Lock interface resolution after 0
public class MyThread implements Runnable{
  int i = 30;
  //JDK5. Sync lock interface from 0 (lock)
  static ReentrantLock lock = new ReentrantLock();//ReentrantLock is the Lock interface implementation class
  @Override
  public void run() {
      while(true) {
          lock.lock();
          if (i > 0)//Manual locking
              System.out.println(i--);
          else
              break;
          lock.unlock();//Manual unlocking
      }
  }
}
public class Test {
  public static void main(String[] args) {
      MyThread m = new MyThread();
      new Thread(m).start();
      new Thread(m).start();
  }
}

Deadlock problem

public static void main(String[] args) {
      Object a = new Object();
      Object b = new Object();
      new Thread(){//Thread one
          @Override
          public void run() {
              synchronized(a){
                  System.out.println("a-");
                  try {
                      sleep(1000);//sleep increases deadlock probability
                  }catch (Exception e){
                      e.printStackTrace();
                  }
                  synchronized(b){
                      System.out.println("a-b");
                  }
              }
          }
      }.start();
      new Thread(){//Thread two
          @Override
          public void run() {
              synchronized(b){
                  System.out.println("b-");
                  try {
                      sleep(1000);
                  }catch (Exception e){
                      e.printStackTrace();
                  }
                  synchronized(a){
                      System.out.println("b-a");
                  }
              }
          }
      }.start();
  }

Thread 1: a lock nested b lock,
Thread 2: b lock nested a lock
If thread 1 executes lock B while thread 2 executes lock a, then the b lock of thread 1 cannot be executed (occupied by thread 2). Similarly, the a lock in thread 2 cannot be executed. Cause two threads to block, which is the deadlock problem
The output is as follows:

Thread communication

Methods related to thread communication (member methods of Object class)

methodeffect
wait()Block the current thread and unlock the lock in the thread
notify()Recover another blocked thread containing the current lock (based on thread priority)
notifyAll()Recover all blocked threads that contain the current lock

All methods can only be invoked in the synchronous code block and the caller is a lock.

JDK5. How threads are created after 0

  • Implement the Callable interface, override the call() method in the implementation class, and call() has a return value
    See code for specific use:
public class MyThread implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("Thread executing....");
        return Integer.valueOf("20");
    }
}
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyThread m = new MyThread();
        FutureTask f = new FutureTask(m);//Return value storage class
        Thread t = new Thread(f);
        t.start();
        //Get return value
        Object i = f.get();
        System.out.println("Return value:" + i);

    }

This approach enables generic programming

  • Thread pool
    The common method in the actual development process is to create multiple threads in advance and reallocate threads when there are tasks Avoid creating and destroying threads many times, save time and facilitate thread management.
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //ExecutorService is the interface of thread pool
        //Executors is a tool class. You can create a new thread pool
        ExecutorService s = Executors.newFixedThreadPool(10);//Thread pool of 10 threads
        Object o = s.submit(new Callable(){//The submit method is applicable to callable
            @Override
            public Object call() throws Exception {
                System.out.println("callable In execution");
                return null;
            }
        }).get();
        
        s.execute(new Runnable() {//execute applies to Runnable
            @Override
            public void run() {
                System.out.println("Runable In execution");
            }
        });
        s.shutdown();//Terminate thread pool
    }

Set thread pool properties to facilitate management

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ThreadPoolExecutor tp =(ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        tp.setCorePoolSize(20);//Thread pool property settings
        tp.setMaximumPoolSize(100);
    }
}

Added by stemp on Wed, 12 Jan 2022 08:43:19 +0200