Java Multithread concurrent 09 -- how to realize data sharing between threads and within threads

This article will bring you Java blocking queue related only. Pay attention to my official account "Java face code" to learn more about Java knowledge.

Data sharing between threads

The main way of multithreading communication in Java is to share memory. There are two main concerns of shared memory: visibility and order atomicity. Java Memory Model (JMM) solves the problem of visibility and order, while lock solves the problem of atomicity. Ideally, we want to achieve "synchronization" and "mutual exclusion". There are the following general implementation methods:

Abstract data into a class

Abstract the data into a class, and take the operation of the data as the method of the class, so the design can be easily synchronized, as long as "synchronized" is added to the method.

public class MyData {
    private int j = 0;

    public synchronized void add() {
        j++;
        System.out.println("thread" + Thread.currentThread().getName() + "j For:" + j);
    }

    public synchronized void dec() {
        j--;
        System.out.println("thread" + Thread.currentThread().getName() + "j For:" + j);
    }

    public int getData() {
        return j;
    }
}

public class AddRunnable implements Runnable {
    MyData data;

    public AddRunnable(MyData data) {
        this.data = data;
    }

    public void run() {
        data.add();
    }
}

public class DecRunnable implements Runnable {
    MyData data;

    public DecRunnable(MyData data) {
        this.data = data;
    }

    public void run() {
        data.dec();
    }

    public static void main(String[] args) {
        MyData data = new MyData();
        Runnable add = new AddRunnable(data);
        Runnable dec = new DecRunnable(data);
        for (int i = 0; i < 2; i++) {
            new Thread(add).start();
            new Thread(dec).start();
        }
    }
}

Runnable object as an inner class of a class

The Runnable object is regarded as the inner class of a class, and the shared data is regarded as the member variable of this class. The operation methods of each thread to the shared data are also encapsulated in the outer class, so as to realize the synchronization and mutual exclusion of each operation of the data. As each Runnable object of the inner class, these methods of the outer class are called.

public class MyData {
    private int j = 0;

    public synchronized void add() {
        j++;
        System.out.println("thread" + Thread.currentThread().getName() + "j For:" + j);
    }

    public synchronized void dec() {
        j--;
        System.out.println("thread" + Thread.currentThread().getName() + "j For:" + j);
    }

    public int getData() {
        return j;
    }
}

public class TestThread {
    public static void main(String[] args) {
        final MyData data = new MyData();
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                public void run() {
                    data.add();
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    data.dec();
                }
            }).start();
        }
    }
}

Intra thread data sharing (ThreadLocal)

The function of ThreadLocal is to provide local variables within a thread, which play a role in the thread's life cycle, reducing the complexity of transferring some common variables between multiple functions or components within the same thread.

ThreadLocalMap (a property of thread)

  1. Each thread has its own ThreadLocalMap class object, which can keep the thread's own object in it. Each pipe has its own object, and the thread can access its own object correctly;
  2. Take a common ThreadLocal static instance as the key, save the references of different objects to the ThreadLocalMap of different threads, and then get the object saved by your own thread through the get() method of this static ThreadLocal instance everywhere the thread executes, avoiding the trouble of passing this object as a parameter;
  3. ThreadLocalMap is actually a property in a Thread. It defines threadlocal.ThreadLocalMap threadlocales = null in the Thread class;

Applicable scenario

The most common scenario of ThreadLocal is to solve database connection, Session management, etc., and realize data sharing within threads.

private static final ThreadLocal threadSession = new ThreadLocal();
public static Session getSession() throws InfrastructureException {
    Session s = (Session) threadSession.get();
    try {
        if (s == null) {
            s = getSessionFactory().openSession();
            threadSession.set(s);
        }
    } catch (HibernateException ex) {
        throw new InfrastructureException(ex);
    }
    return s;
}

Multithreading and concurrency series recommendations

Java multithreading concurrent 08 -- the application of lock in Java

Java Multithread concurrent 07 -- implementation of lock in Java

Java multithreading 06 -- CAS and AQS

Java multithreading concurrency 05 -- do you know so many locks

Java Multithread concurrency 04 -- reasonable use of thread pool

Java multithreading concurrency 03 -- what is thread context and how threads are scheduled

Java Multithread concurrency 02 -- thread life cycle and common methods, have you mastered

Java Multithread concurrency 01 -- how to create and terminate a thread

Tags: Java Session Database

Posted on Mon, 23 Mar 2020 05:48:08 -0700 by turkman