The second pass of Java foundation - 12 - multithreading - synchronization - Communication

Keywords: Java

Causes of multithreading security problems

  1. Data shared by multiple threads
  2. There are multiple threads operating on shared data
  3. When one thread operates the shared data, other threads participate in the operation, which will lead to thread safety problems

Resolve thread safety issues

  1. Locking mechanism
  2. Idea: encapsulate the shared data. When a thread operates, other threads cannot participate in the operation. After the thread is executed, others can participate in the operation
  3. Synchronized code blocks can solve this problem: synchronized

Advantages and disadvantages of synchronization

  1. Benefits: resolve thread safety issues
  2. Disadvantages: the execution efficiency will be low, and the threads outside the synchronization will judge the synchronization lock

Lock used by synchronization function and synchronization code block

  1. The lock used by the synchronization function is this, fixed
  2. Synchronization code blocks can use any lock
  3. A lock is an object

Lock used by static synchronization function

  1. The lock used is the bytecode file Object to which the function belongs, that is, the class Object. It can be obtained by using the getClass method in the Object or represented by (current class name. Class)

How threads are created

  1. Inherit Thread
  2. Implement Runnbale
    1. The thread task is separated from the subclass of thread and encapsulated separately
    2. It avoids the limitation of Java single inheritance
    3. More commonly used
  3. callable
  4. Thread pool

Singleton mode under multithreading

  1. Hungry Han style
    1. The object is created as soon as the class is loaded
  2. Lazy style
    1. Create objects only when you want to use them
  3. Using singleton mode and hungry Chinese mode under multithreading is relatively simple to implement
  4. Lazy needs to be solved, thread insecurity and efficiency problems
    Use synchronization to solve thread safety problems, and use if judgment to solve efficiency problems
//Lazy style
class Single{
    private static Single s = null;
    private Single(){}
    public static Single getInstance(){
        if(s==null){
            synchronized (Single.class){
                if (s==null){
                    return new Single();
                }
            }
        }
        return s;
    }
}

Producer consumer model

Implementation of synchronized mode: in the case of multi consumer and multi producer mode, you can only use notifyAll(), and the use of notify() may deadlock.

package com.bixiangdong.thread;

class Resource{
    private String name;
    private int count=1;
    private boolean flag=false;
    public synchronized void set(String name){
        while (flag){
            try {
                this.wait();
            }catch (InterruptedException e){

            }
        }
        this.name=name;
        count++;
        System.out.println(Thread.currentThread().getName()+"----producer----"+this.name+count);
        flag=true;
        notifyAll();//notifyAll is used here because if there are multiple producers, the thread of the producer may always be awakened by notify, and then a deadlock may occur because flag = flag always waits
    }
    public synchronized void get(){
        while (!flag){
            try {
                this.wait();
            }catch (InterruptedException e){

            }
        }
        System.out.println(Thread.currentThread().getName()+"----consumer----"+this.name+count);
        flag=false;
        notifyAll();
    }
}
class Productor implements Runnable{
    private Resource r;
    public Productor(Resource r){
        this.r=r;
    }

    @Override
    public void run() {
        while (true){
            r.set("milk");
        }
    }
}
class Customer implements Runnable{
    private Resource r;
    public Customer(Resource r){
        this.r=r;
    }

    @Override
    public void run() {
        while (true){
            r.get();
        }
    }
}
public class Demo03 {
    public static void main(String[] args) {
        Resource resource = new Resource();
        Productor productor = new Productor(resource);
        Customer customer = new Customer(resource);
        new Thread(productor).start();
        new Thread(customer).start();
    }
}

Lock implementation method: JDK1.5 supports the lock method, which can realize that a lock has multiple condition s, which can realize that the producer can notify the consumer more accurately. The producer can only wake up one consumer, and so can the consumer

package com.bixiangdong.thread;


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Resource2{
    private String name;
    private int count=1;
    private boolean flag=false;

    //Create lock
    Lock lock = new ReentrantLock();
    //Create two sets of monitors from existing locks
    Condition pro_con = lock.newCondition();
    Condition cus_con = lock.newCondition();

    public void set(String name){
        //Set lock
        lock.lock();
        while (flag){
            try {
                pro_con.await();
            }catch (InterruptedException e){

            }
        }
        this.name=name;
        count++;
        System.out.println(Thread.currentThread().getName()+"----producer----"+this.name+count);
        flag=true;
        //notifyAll();// NotifyAll is used here because if there are multiple producers, the thread of the producer may always be awakened by notify, and then a deadlock may occur because flag = flag always waits
        cus_con.signal();//Just wake up one consumer
        //Release lock
        lock.unlock();
    }
    public void get(){
        lock.lock();
        while (!flag){
            try {
                cus_con.await();
            }catch (InterruptedException e){

            }
        }
        System.out.println(Thread.currentThread().getName()+"----consumer----"+this.name+count);
        flag=false;
        //notifyAll();
        pro_con.signal();
        lock.unlock();
    }
}
class Productor2 implements Runnable{
    private Resource2 r;
    public Productor2(Resource2 r){
        this.r=r;
    }

    @Override
    public void run() {
        while (true){
            r.set("milk");
        }
    }
}
class Customer2 implements Runnable{
    private Resource2 r;
    public Customer2(Resource2 r){
        this.r=r;
    }

    @Override
    public void run() {
        while (true){
            r.get();
        }
    }
}
public class Demo04 {
    public static void main(String[] args) {
        Resource2 resource = new Resource2();
        Productor2 productor = new Productor2(resource);
        Customer2 customer = new Customer2(resource);
        new Thread(productor).start();
        new Thread(productor).start();
        new Thread(productor).start();
        new Thread(customer).start();
        new Thread(customer).start();
        new Thread(customer).start();
    }
}

The difference between wait and sleep

  1. wait can specify the time or not
  2. sleep must specify a time
    During synchronization, the execution right of cpu is different from that of lock
  3. wait: release the execution authority and release the lock
  4. sleep: release the execution authority without releasing the lock

End of thread

  1. If the run method in the thread ends, the thread ends
  2. How to end the run method by changing the flag
    Marking method
package com.bixiangdong.thread;
class A1 implements Runnable{
    public boolean flag = true;
    @Override
    public void run() {
        while (flag){
            System.out.println("Always running"+Thread.currentThread().getName());
        }
    }
}

public class Demo05 {
    public static void main(String[] args) {
        A1 a1 = new A1();
        new Thread(a1).start();
        new Thread(a1).start();
        int num=0;
        for (;;){
            num++;
            if (num==100000){
                a1.flag=false;
                break;
               // System.exit(0);
            }
            System.out.println("-----------");
        }
    }
}

Posted by PW on Tue, 02 Nov 2021 11:10:38 -0700