Java multi-threaded programming - (4) - introduction and use of inter-thread communication mechanisms

Previous:

Java multi-threaded programming - (1) - Synchronized thread-safe and lock concept

Java multi-threaded programming - (2) - reentrant locks, and other basic characteristics of Synchronized

Java multi-threaded programming - (3) - introduction and use of thread local ThreadLocal

Inter-thread communication Introduction
We know that the thread is operating system independent individual, but this alone is not a special kind of treatment between individuals make it a whole, there is no exchange and communication between threads, then he is a separate individuals, not enough to form a strong overall strong interaction.

To improve the mechanism of mutual cooperation between CPU utilization and thread of each, Java is an implementation of inter-thread communication is: Inter wait / notify thread communication, the following will learn together about the communication mechanism between this thread.

Do not use wait / notify mechanism to achieve inter-thread communication
if we do not need to introduce the use of the following mechanisms, that how we achieve communication between two threads which, under the watching a piece of code to achieve is to fill two threads in a List data:

MyList Code:

public class MyList {

    private List list = new ArrayList();

    void the Add public () {
        List.add ( "I element");
    }

    public int size() {
        return list.size();
    }

}

Thread A:

public class ThreadA extends Thread {

    private MyList list;

    public ThreadA(MyList list) {
        super();
        this.list = list;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                list.add();
                System.out.println("添加了" + (i + 1) + "个元素");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

线程B:

public class ThreadB extends Thread {

    private MyList list;

    public ThreadB(MyList list) {
        super();
        this.list = list;
    }

    @Override
    public void RUN () {
        the try {
            the while (to true) {
                IF (list.size () == 5) {
                    System.out.println ( "== 5 a, b thread to be pulled out!");
                    The throw new new InterruptedException ();
                }
            }
        } the catch (InterruptedException E) {
            e.printStackTrace ();
        }
    }
}

test class test:

public class Test {

    public static void main(String[] args) {
        MyList myList = new MyList();

        ThreadA a = new ThreadA(myList);
        a.setName("A");
        a.start();

        B = new new and that ThreadB and that ThreadB (myList);
        b.setName ( "B");
        b.start ();
    }
}

The results:

Added an element
adds two elements
added three elements
to add a fourth element
added five elements
== 5 a, b thread to be pulled out!
java.lang.InterruptedException
    AT text.ThreadB.run (ThreadB.java:20)
added six elements
added element 7
adds eight elements
added nine elements
added 10 elements

can be seen that the set of List the data for the five time thread B exits, although enables communication between two threads, but our code is thread B has been implementing a while (true) loop until a length of only 5 to terminate the execution, apparently ways is very resource-intensive. So, we need a mechanism to avoid the above-mentioned operation but also enables communication between multiple threads, this is the next step is to learn the "wait / notify inter-thread communication."

What is waiting / notification mechanism
reason is very simple, just like we go to the bank to do business, ticket number after the door, so when we reach will be broadcast announcements do business like this is a very real scenario, we took the ticket number on We need to wait, such as the clerk came time ticket number will be broadcast notification.

Java wait / notification mechanism implemented
method corresponding Java wait / notification is wait () / notify (), these two methods are in the superclass Object, as shown below:

The reason is a method of super class Object, we can be simply understood: We know several articles on any object can be used as a lock, and the wait () / notify () is called by the lock, thought of this nature can appreciate here's the clever design to place.

A, wait method

Effect (1) Method wait () is to code execution thread is currently waiting, which will be threaded into the "pre-execution queue", and the wait () is located at a stop code is executed until notified or interrupt occurs.

(2) before the call to wait (), the thread must acquire the lock object level, this is a very important place, many times we may forget it, that can only be called wait () in a synchronized block synchronization method or methods .

(3) Also note that the wait () is to release the lock, that is, after the execution to wait () method, the current thread releases the lock, the current returns from the wait () method, thread and other threads compete to regain lock.

Two, notify method

Like (1) and wait () method, notify () method should be called in synchronized block or synchronized method, that is, before the call, the thread must acquire the object level lock of the object.

(2) This method is used to notify that other threads may be waiting for this lock object, if there are multiple threads waiting, by the thread scheduling randomly selected wait state form wherein a thread of its notification notify, and wait for it to acquire the object object lock.

(3) It should be noted that, after performing notify method, the current thread will not release the object lock in its possession immediately, but will release the object lock after the execution, the thread does not get notified immediately object lock , but after executing the wait notify method, the object lock is released before they can obtain the object lock.

(3) notifyAll () notifies all waiting threads all share the same resources of exit from the waiting state, runnable, re-compete for the object lock.

Three, wait () / notify () Methods

(1) wait () / notify () for a set of synchronized keyword used together, because they need to acquire the object lock of the object;

(2) wait method is to release the lock, notify the lock is not released;

Four states (3) below the thread:

Sample Code Communication between the threads wait / notify
The transformation code is not used wait / notify the following:

MyList Code:

public class MyList {

    private static List list = new ArrayList();

    static void the Add public () {
        List.add ( "I element");
    }

    public static int size() {
        return list.size();
    }
}

线程A:

public class ThreadA extends Thread {

    private Object lock;

    public ThreadA(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void run() {
        try {
            synchronized (lock) {
                if (MyList.size() != 5) {
                    System.out.println("wait begin " + System.currentTimeMillis());
                    lock.wait();
                    System.out.println("wait end  " + System.currentTimeMillis());
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

线程B:

public class ThreadB extends Thread {

    private Object lock;

    public ThreadB(Object lock) {
        super();
        this.lock = lock;
    }

    @Override
    public void RUN () {
        the try {
            the synchronized (Lock) {
                for (int I = 0; I <10; I ++) {
                    MyList.add ();
                    IF (MyList.size () ==. 5) {
                        lock.notify ();
                        System.out.println ( "already notified!");
                    }
                    System.out.println ( "added" + (i + 1) + " elements!");
                    the Thread.sleep (1000);
                }
            }
        } the catch (InterruptedException E) {
            e.printStackTrace ();
        }
    }
}

test code:

public class Run {

    public static void main(String[] args) {
        try {
            Object lock = new Object();
            ThreadA a = new ThreadA(lock);
            a.start();
            Thread.sleep(50);
            ThreadB b = new ThreadB(lock);
            b.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果:

wait begin 1507634541467
added an element!
adds two elements!
added three elements!
added four elements!
has given notice!
5 additional elements!
Added six elements!
Added seven elements!
Adds eight elements!
Added nine elements!
Add 10 elements!
The wait End 1507634551563

above example has been achieved simply waiting notification mechanism, and we can also see, though only after obtaining the object lock thread B notification when a fifth element, and achieve thread a thread B executed, which may also explain, wait method is to release the lock and notify method is not release the lock.

Another case: using wait / notify analog BlockingQueue blocking queue
BlockingQueue queue is blocked, we need to implement is blocked in and get data, design ideas are as follows:

(1) initialize the maximum queue length is 5; 
(2) a new addition of the time, determines whether the length is 5, if it is 5 waits insertion; 
(3) when necessary consumption elements, determines whether 0, if 0 waiting for the consumer;

Codes are as follows:

public class MyQueue {

    // 1, requires a set of elements for installing the
    Private Final the LinkedList <Object> = new new List the LinkedList <> ();
    // 2, requires a counter
    Private Final of AtomicInteger of AtomicInteger new new COUNT = (0);
    //. 3, specify upper and lower
    Private Final the maxSize = int. 5;
    Private Final the minSize int = 0;

    5 // initialization lock object
    private final Object lock = new Object ( );

    / **
     * PUT method
     * /
    public void PUT (Object obj) {
        the synchronized (Lock) {
            // the maximum can not add, enter until
            the while (count.get () == maxSize) {
                the try {
                    lock.wait ();
                the catch} (InterruptedException E) {
                    e.printStackTrace ();
                }
            }
            List.add (obj); // added element
            count.getAndIncrement (); // counter is incremented
            System.out.println ( "element" + obj + "is Add ");
            lock.notify (); // notify a thread blocking method further
        }
    }

    / **
     * GET method
     * /
    public Object GET () {
        Object the TEMP;
        the synchronized (Lock) {
            // minimum, there is no element of consumption can not enter until
            the while (count.get () == minSize) {
                the try {
                    Lock. the wait ();
                } the catch (InterruptedException E) {
                    e.printStackTrace ();
                }
            }
            count.getAndDecrement ();
            TEMP = list.removeFirst ();
            System.out.println ( "element" + temp + "to be consumed") ;
            lock.notify ();
        }
        return TEMP;
    }

    private int size() {
        return count.get();
    }

    public static void main(String[] args) throws Exception {

        final MyQueue myQueue = new MyQueue();
        initMyQueue(myQueue);

        Thread t1 = new Thread(() -> {
            myQueue.put("h");
            myQueue.put("i");
        }, "t1");

        Thread t2 = new Thread(() -> {
            try {
                Thread.sleep(2000);
                myQueue.get();
                Thread.sleep(2000);
                myQueue.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");

        t1.start();
        Thread.sleep(1000);
        t2.start();

    }

    static void initMyQueue Private (MyQueue myQueue) {
        myQueue.put ( "A");
        myQueue.put ( "B");
        myQueue.put ( "C");
        myQueue.put ( "D");
        myQueue.put ( " E ");
        System.out.println (" current number of elements: "+ myQueue.size ());
    }
}

The results:

 A added element is 
 an element b be added 
 element c is added 
 elements are added d 
 elements e are added 
number of current element: 5
 element is a Consumer 
 element h is added 
 elements b are consumed 
 element i is added 

Additional Notes
(1) wait ( ), and notify () method to be invoked in a sync block or synchronization method, i.e. prior to the call, the thread must acquire the lock object level of the object.

(2) wait method is to release the lock, notify the lock is not released;

(3) notify each thread wait waiting wake states are random, and each only a wake-up;

(4) notifAll wake wait wait state each thread to make it competitive again acquire the object lock, the highest priority thread that is executed first;

(5) When the thread is in wait () status, the calling thread object's interrupt () method will InterruptedException anomaly;

Other knowledge
(1) inter-process communication:

Conduit (pipe), named pipes (named pipe), the signal amount (semophore), the message queue (message queue), the signal (signal), shared memory (shared memory), the socket (Socket);

(2) communication between threads range:

1, the lock mechanism 
1.1 mutex: provides a method for preventing in exclusive manner concurrent modification data structure. 
1.2 write lock: read simultaneously allows multiple threads to share data, and write operations are mutually exclusive. 
1.3 condition variables: You can block the process atomically, until a certain condition is true so far.

Conditions for testing is under protection of a mutex carried out. Always use condition variables together with a mutex.

2, semaphore mechanism: a thread unnamed semaphores and semaphore famous thread 
3, the signaling mechanism: inter-process is similar to the signal processing.

The main purpose of communication between threads for thread synchronization, so there is no thread communication mechanisms such as the exchange of data for process communication.
--------------------- 
Author: Xu Gen 
Source: CSDN 
Original: https: //blog.csdn.net/xlgen157387/article/details/78195817 
Disclaimer: This article as a blogger original article, reproduced, please attach Bowen link!

Guess you like

Origin blog.csdn.net/hellozhxy/article/details/92786283