Summary of Java multi-threaded interview knowledge points (super detailed summary)

1. The sleep() method, wait() method, yield() method, interrupt() method, notify(), notifyAll() method
1. sleep() method:
The sleep method is a static method of Thread;
the function of the sleep method is Let the thread sleep for a specified time, and automatically resume the execution of the thread when the time arrives; the
sleep method will not release the thread lock;

2. wait() method:
The wait method is a method of Object;
any object can call the wait method. Calling the wait method will suspend the caller's thread and make the thread enter a waiting area called waitSet until other threads call notify of the same object

The method will reactivate the caller;
when the wait method is called, it will release the lock mark it occupies, so that the synchronized data in the object where the thread is located can be used by other threads,
so the wait() method must be synchronized When used in a block, the notify() and notifyAll() methods will both modify the "lock mark" of the object, so they all need to be called in the synchronized block.
If it is not called in the synchronized block, although it can be edited and passed, the runtime will report IllegalMonitorStateException (Illegal monitoring state exception);

3. The yield() method:
The yield() method means to stop the current thread, make the thread enter the executable state, and let the threads of the same priority run. If there is no thread of the same priority, the yield() method
will work;
4. notify() and nofityAll() methods;
notify() will notify a thread in wait() state; if multiple threads are in wait state, he will wake up one of them randomly;
notifyAll() will notify all The thread in the wait() state, which thread to execute depends on the priority;
2. The state of the java thread The
java thread has four states: generated, ready, executed, blocked, and dead
Generated : the thread is created, but Not started (start() is not called)
Ready: the thread is started (start() is called), in an executable state, waiting for CPU scheduling;
Execution: the normal running state of the thread;
death: a thread ends normally executing;
blocking:
( 1), waiting for blocking: the running thread executes the wait() method, and the jvm will put the thread into the waitSet thread pool (release the lock);
(2), synchronization blocking (deadlock): the running thread is acquiring the synchronization of other objects The lock is that the synchronization lock of the object is occupied by other thread locks, and the jvm will put the thread into the thread pool;
(3) Other blocking: the running thread executes the sleep method or executes the t.join() method, and is blocked by If another thread is interrupted, the JVM puts the thread into a blocking state. When the sleep times out or the join thread ends

The thread re-enters the ready state when the warp ends.
3. Java's method of implementing multi-threading: inheriting the Thread class, implementing the runnable interface, and implementing the Callable interface
1. Inheriting the Thread class:
public class MyThread extends Thread {
  public void run() {
   System.out.println (“MyThread.run()”);
  }
}
MyThread myThread1 = new MyThread();
myThread1.start();

2. Implement the Runnable interface:
public class MyThread immplements Runnable {
public void run(){
sysout.out.println(“MyThread.run()”);
}
}
MyThread runThread = new MyThread();
Thread runThread = new Thread(runThread ,"");
runThread.start();
3. Implement the Callable interface and create a Thread thread through the FutureTask wrapper

Advantages and disadvantages:
1) Inheriting the Thread class is single inheritance, and implementing the Runnable method is multi-implementation, so in terms of flexibility, it is more flexible to implement the Runnable method;
2) By implementing the Runnable interface, resources in multiple threads can be realized Sharing;
3) Increase the robustness of the code, the code can be shared by multiple threads, and the code and data are independent;
4) The thread pool can only be placed in threads that implement Runnable or callable classes, and cannot be directly placed in threads that inherit the Thread class;

4. Thread scheduling
1. Adjust the on-site priority: Java threads have priority, and threads with higher priorities get more running opportunities (running time);
static int Max_priority The highest priority a thread can have, the value is 10;
static int MIN_PRIORIYT The lowest priority a thread can have, the value is 1;
static int NORM_PRIORITY The default priority assigned to the thread, the value is 5;
The setPriority() and getPriority() methods of the Thread class are used to set and get the thread's priority respectively;
2. Thread sleep: Thread.sleep(long millins) turns the thread into a blocking state;
3. Thread waiting: Object.wait() method, releases the thread lock, so that the thread enters the waiting state until it is woken up by other threads (notify() and notifyAll());
4. Thread yield: The Thread.yeild() method suspends the currently executing thread, makes it enter the waiting state, and gives the execution opportunity to the thread of the same priority or higher priority. high priority

Or a thread of the same priority, the thread will continue to execute;
5. Thread join: join() method, call the join() method of another thread in the current thread, then the current thread will enter the blocking state until another process is running End, the current thread is blocked again

is ready state;

5. Some common methods of thread class:
1), sleep(): force a thread to sleep for N milliseconds;
2), isAlive(): determine whether a thread is alive;
3), join(): thread cut in queue;
4), activeCount (): the number of active threads in the program;
5), enumerate(): enumerate the threads in the program;
6), currentThread(): get the current thread;
7), isDeamon(): whether a thread is a daemon thread;
8 ), setName(): set a name for the thread;
9), wait(): thread waiting;
10), notify(): wake up a thread;
11), setPriority(): set the priority of a thread;

Six: Thread synchronization
Thread synchronization mainly uses the synchronized keyword; there are two ways to achieve it: 1. As a keyword to modify a method in the class; 2. To modify an area (code) in the method;
1. Treat synchronized as a method (function ) modifier:
public class Name{//class name Name
//getName method
public synchronized void getName(){
system.out.println("123");
}
}
class Name has two instance objects n1 and n2, At this time, there are two threads t1 and t2; n1 executes the getName() method in thread t1 (to obtain the lock of this method), then n1 cannot execute getName() in thread t2 (

) method, but n2 can execute the getName() method in the t1 thread, and similarly n2 cannot execute the getName() method in the t2 thread at the same time; so in fact, the synchronized lock is getName()

The object of this method (n1 and n2), not the method of the lock, this needs to be understood;
2. Synchronized block, the example code is as follows:
public void getName(Object o) {
synchronized(o){
//TODO
}
}
Here it means Lock this variable o;
here is a thread-safe singleton mode
public class Car{
//Constructor
private Car();
//Create a static private empty constant car
private static Car car = null;
/ /Open a static public method to get the instance
public static getInstance(){
if(car == null){
synchronized(Car.getClass()){
if(car == null){
car ​​= new Car() ;
}
}
}
return car;
}
}
7. Thread data transfer
In the traditional development mode, when we call a function, the data is passed in through the parameters of the function, and the final calculation is returned through the return value of the function result, but in multithreaded asynchronous development

In the mode, the transmission and return of data is very different from the synchronous development mode. Because the execution and results of threads are unpredictable, it is not possible to pass function parameters and functions like functions when passing and returning data.

return statement to return data;
1. Pass the parameter
package mythread through the constructor;
public class MyThread1 extends Thread
{
private String name;
public MyThread1(String name)
{
this.name = name;
}
public void run()
{
System.out. println("hello" + name);
}
public static void main(String[] args)
{
Thread thread = new MyThread1("world");
thread.start();
}
}
Since this method is creating a thread object At the same time, the data is passed, so the data is already in place before the thread runs, so that the phenomenon that the data is passed in after the thread runs will not be caused. if

To pass more complex data, you can use data structures such as collections, classes, etc. Although it is safer to use the constructor to pass data, it will cause a lot of inconvenience if there is a lot of data to be passed. Due to Java

There is no default parameter, in order to achieve the effect similar to the default parameter, you have to use overloading, which not only makes the construction method itself too complicated, but also greatly increases the number of construction methods. Therefore, to avoid this

, you have to pass data through class methods or class variables.
2. Passing data through variables and methods There are generally two opportunities to pass data
into an object. The first opportunity is to pass in the data through the constructor when the object is created, and the other opportunity is to define a series of public in the class. method or variable (or

call it a field). Then after creating the object, assign values ​​one by one through the object instance. The following code is a modification of the MyThread1 class, using a setName method to set the name variable:
package mythread;
public class MyThread2 implements Runnable
{
private String name;
public void setName(String name)
{
this.name = name;
}
public void run()
{
System.out.println("hello" + name);
}
public static void main(String[] args)
{
MyThread2 myThread = new MyThread2();
myThread.setName("world");
Thread thread = new Thread(myThread); thread.start
();
}
}
3. Finally, data sharing between threads, the implementation of the producer-consumer model is posted below:
Implementation scenario: There is a steamed bread room, the producer produces steamed bread, and the consumer To consume steamed buns, when the number of steamed buns is 0, stop consumption and start production; when the number of steamed buns produced is greater than 5, stop production and start consumption;
Analysis:
1. Steamed bread class: variables: mt (steamed bread), num (number of steamed breads), eatMantou() (method of eating steamed bread), produceMantou() (method of producing steamed bread), where the object is passed through the construction method
2. Consumer class : Eating steamed buns, which is used to call the steamed bun eating method of the steamed bun object;
3. Producer class: Produce steamed buns, that is, used to call the steamed bun producing method of the steamed bun object;
4. Test class: used for testing; the
specific code is as follows:
package com .yp.producerAndconsumer;
/**
* @prama product in producer consumer issue
*/
public class Mantou {
private String mt;
private int num;

public String getMt() {
    return mt;
}

public void setMt(String mt) {
    this.mt = mt;
}

public int getNum() {
    return num;
}

public void setNum(int num) {
    this.num = num;
}

public Mantou(String mt, int num) {
    this.mt = mt;
    this.num = num;
}

/**
 * 消费馒头
 */
public synchronized void eatMantou(){
    //如果馒头数量大于0,则消费馒头
    while(num >0){
        System.out.println("消费后有:---"+this.num+"\n");
        num--;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    while(num ==0){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.notify();
    }

}

/**
 * 生产馒头
 */
public synchronized void produceMantou(){
    while(num<5){
        System.out.println("生产后有:---"+this.num+"个"+"\n");
        num ++;
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    while(num ==5){
        try {
            this.wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.notify();
    }
}

}

Consumer class;
package com.yp.producerAndconsumer;

public class Consumer implements Runnable {
private Mantou m ;
public Consumer(Mantou m) {
this.m = m;
}

@Override
public  void run() {
    m.eatMantou();
}

}
Producer class:
package com.yp.producerAndconsumer;

public class Producer implements Runnable{
Mantou m ;
public Producer(Mantou m) {
this.m = m;
}

@Override
public  void run() {
    m.produceMantou();
}

}
Test class:
package com.yp.producerAndconsumer;

/**
* @param 生产者消费者问题
* @author YangPeng
*
*/
public class ProducerAndConsumer {
public static void main(String[] args) {
Mantou mantou = new Mantou(“花卷”,4);
Producer producer = new Producer(mantou);
Consumer consumer = new Consumer(mantou);
Thread t1 = new Thread(producer);
Thread t2 = new Thread(consumer);
t1.start();
t2.start();

}

}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325899105&siteId=291194637