[Java Concurrent Programming] 02. Use of Exchanger

Keywords: Java github Programming

Java concurrent programming is a column I just opened. It records my notes and Thoughts on learning Java concurrent programming. I hope you can make progress together. Column address: http://blog.csdn.net/column/details/14538.html Welcome your attention.

All the code in this column will be uploaded to GitHub.
GitHub address is: https://github.com/mrbcy/JavaConcurrentLearn

I would have had time to read and program again in a few days, but today I received a notice that the column application has been approved. That's nothing to say. Today I must update one.

This time we focus on Exchanger, which is mainly used to transfer data between two threads, which is more convenient than wait/notify used in the producer / consumer model. This blog will give you an example of an Exchanger class passing arbitrary types of data between two threads.

Exchanger class structure and use is very simple, mainly to learn the use of exchange() method.

Blocking properties of method exchange()

exchange() method in Exchanger class has blocking property. After calling this method, it will wait for other threads to get data. If no other threads get data, it will always block waiting.

The sample code is as follows:

ThreadA.java

package tech.mrbcy.javaconcurrentlearn.e02_1;

import java.util.concurrent.Exchanger;

public class ThreadA extends Thread{
    private Exchanger<String> exchanger;

    public ThreadA(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("Thread in A Get threads in B Value:" + exchanger.exchange("AAAAA"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

Run.java

package tech.mrbcy.javaconcurrentlearn.e02_1;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }
}

After running, ThreadA will block. The effect is as follows:

Pass values using exchange() method

In the above example, add another class, ThreadB

ThreadB.java

package tech.mrbcy.javaconcurrentlearn.e02_2;

import java.util.concurrent.Exchanger;

public class ThreadB extends Thread{
    private Exchanger<String> exchanger;

    public ThreadB(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("Thread in B Get threads in A Value:" + exchanger.exchange("BBBBB"));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}

Then make a slight change to Run

package tech.mrbcy.javaconcurrentlearn.e02_2;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        ThreadB b = new ThreadB(exchanger);
        a.start();
        b.start();
    }
}

When you run it, you can see that ThreadA and ThreadB get the values passed from each other.

Operation results:

Get the value in thread A in thread B: AAAAA
 Get the value in thread B in thread A: BBBBB B B

Timeout of exchange() method

The caller of the exchanger() method can also specify how long it takes for no other thread to retrieve data, and then no longer wait to throw a timeout exception.

Modify ThreadA again, and then change Run back to its original look.

ThreadA.java

package tech.mrbcy.javaconcurrentlearn.e02_3;

import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ThreadA extends Thread{
    private Exchanger<String> exchanger;

    public ThreadA(Exchanger<String> exchanger) {
        super();
        this.exchanger = exchanger;
    }

    @Override
    public void run() {
        super.run();

        try {
            System.out.println("Thread in A Get threads in B Value:" + exchanger.exchange("AAAAA", 5, TimeUnit.SECONDS));
            System.out.println("A end!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }


}

Run.java

package tech.mrbcy.javaconcurrentlearn.e02_3;

import java.util.concurrent.Exchanger;

public class Run {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();

        ThreadA a = new ThreadA(exchanger);
        a.start();
        System.out.println("main end!");
    }
}

The results are as follows:

main end!
java.util.concurrent.TimeoutException
    at java.util.concurrent.Exchanger.exchange(Exchanger.java:683)
    at tech.mrbcy.javaconcurrentlearn.e02_3.ThreadA.run(ThreadA.java:20)

summary

Exchanger class can be used to easily transfer data between threads, and there is no restriction on the type of data.

Posted by wwfc_barmy_army on Sun, 31 Mar 2019 21:36:29 -0700