I am Chen PI, an ITer of Internet Coding. I search “Chen PI’s JavaLib” on wechat and read the latest articles as soon as possible, reply to [information], and then I can get the technical materials, electronic books, interview materials of first-line big factories and excellent resume templates carefully arranged by me.

What is the 1 Recovery

The NON-recovery class provided under the JUC package in JDK 1.5 is used to exchange information between two threads. The San_recovery object is a container containing two cells, and the san_recovery method is used to fill the cell. When both cells are filled, the information in the two cells is automatically exchanged and returned to the calling thread, which uses the san_recovery tool to exchange information between the two threads.

The functionality may seem simple, but it can be useful in some situations, such as a game where two players trade equipment; Dating apps match men and women.

The following is a simple simulation of two players exchanging equipment.

 package com.chenpi;
 ​
 import java.util.concurrent.Exchanger;
 ​
 / * * *@Description
  * @AuthorDried tangerine or orange peel *@Date 2021/7/11
  * @Version1.0 * /
 public class ChenPiMain {
 ​
   public static void main(String[] args) throws InterruptedException {
 ​
     Exchanger<String> exchanger = new Exchanger<>();
 ​
     new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Dragon slayer");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhou Zhiruo").start();
 ​
     new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Sword of Heaven");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhang Wuji").start(); }}// The output is as followsTrading success, Zhang Wuji dragon knife trading success, If Zhou Zhitian jian obtainedCopy the code

2 Exchanger,

The Exchager class is used for information exchange between two threads. If one thread calls the Exchange method of the Non-recovery object, it blocks until the other thread exchanges information with it. The exchange information is returned to the calling thread for information exchange.

Exchager also uses spin and CAS mechanisms at the bottom.

Note that if more than two threads invoke the same Exchange method, the result is not expected. As long as two threads meet the condition, the match is considered successful and information is exchanged. The remaining threads that can’t be paired will block and wait until another thread can match it.

 package com.chenpi;
 ​
 import java.util.concurrent.Exchanger;
 ​
 / * * *@Description
  * @AuthorDried tangerine or orange peel *@Date 2021/7/11
  * @Version1.0 * /
 public class ChenPiMain {
 ​
   public static void main(String[] args) {
 ​
     Exchanger<String> exchanger = new Exchanger<>();
 ​
     new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Dragon slayer");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhou Zhiruo").start();
 ​
     new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Sword of Heaven");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhang Wuji").start();
 ​
     new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("The fake Sword of Heaven.");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "ChengKun").start(); }}// The output is as followsTrading success, If Zhou Zhi get false trading success of the sword, Cheng Kun get dragon knifeCopy the code

Of course, the thread waiting for the exchange of information can be interrupted, for example, while the player is waiting for a transaction and suddenly the player is offline, it should be interrupted.

 package com.chenpi;
 ​
 import java.lang.Thread.State;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Exchanger;
 ​
 / * * *@Description
  * @AuthorDried tangerine or orange peel *@Date 2021/7/11
  * @Version1.0 * /
 public class ChenPiMain {
 ​
   public static void main(String[] args) throws InterruptedException {
 ​
     Exchanger<String> exchanger = new Exchanger<>();
 ​
     List<Thread> threads = new ArrayList<>(3);
 ​
     Thread thread1 = new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Dragon slayer");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhou Zhiruo");
     threads.add(thread1);
 ​
     Thread thread2 = new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Sword of Heaven");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "Zhang Wuji");
     threads.add(thread2);
 ​
     Thread thread3 = new Thread(() -> {
       String str = null;
       try {
         str = exchanger.exchange("Fake dragon slayer.");
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
     }, "ChengKun");
     threads.add(thread3);
 ​
     for (Thread thread : threads) {
       thread.start();
     }
 ​
     // Wait 5 seconds
     Thread.sleep(5000);
 ​
     for (Thread thread : threads) {
       System.out.println(thread.getName() + ":" + thread.getState());
       // Interrupt the thread if it is still blocking
       if(thread.getState() == State.WAITING) { thread.interrupt(); }}}}// The output is as followsThe deal is successful, Zhang Wuji gets dragon knife deal is successful, Zhou Zhiru gets the sword of heaven TERMINATED, Cheng Kun is TERMINATEDnull
 java.lang.InterruptedException
     at java.util.concurrent.Exchanger.exchange(Exchanger.java:568)
     at com.chenpi.ChenPiMain.lambda$main$2(ChenPiMain.java:47)
     at java.lang.Thread.run(Thread.java:748)
Copy the code

This demonstrates that a thread will wait forever if it cannot wait for another thread to exchange information with it. Actually, the RECOVERY server can also set the waiting time. For example, the system sets the matching time for the player to exchange equipment to 60 seconds, and if the time is exceeded, the transaction is terminated.

 package com.chenpi;
 ​
 import java.util.concurrent.Exchanger;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 ​
 / * * *@Description
  * @AuthorDried tangerine or orange peel *@Date 2021/7/11
  * @Version1.0 * /
 public class ChenPiMain {
 ​
   public static void main(String[] args) {
 ​
     Exchanger<String> exchanger = new Exchanger<>();
 ​
     new Thread(() -> {
       try {
         // Timeout is set to 5 seconds
         String str = exchanger.exchange("Dragon slayer".5, TimeUnit.SECONDS);
         System.out.println("Successful transaction," + Thread.currentThread().getName() + "Get" + str);
       } catch (TimeoutException e) {
         System.out.println("Time out!");
         e.printStackTrace();
       } catch (InterruptedException e) {
         System.out.println("Abnormal termination of transaction."); e.printStackTrace(); }},"Zhou Zhiruo").start(); }}// The output is as followsThe transaction timed out! java.util.concurrent.TimeoutException at java.util.concurrent.Exchanger.exchange(Exchanger.java:626)
     at com.chenpi.ChenPiMain.lambda$main$0(ChenPiMain.java:22)
     at java.lang.Thread.run(Thread.java:748)
Copy the code

3 Exchanger application

Exchager is useful in applications such as genetic algorithms and pipe design. For example, two threads swap buffers, and the thread filling the buffer gets a freshly emptied buffer from the other thread when it needs it, and passes the filled buffer to the thread clearing the buffer.

 package com.chenpi;
 ​
 import java.awt.image.DataBuffer;
 import java.util.concurrent.Exchanger;
 ​
 / * * *@Description
  * @AuthorDried tangerine or orange peel *@Date 2021/7/11
  * @Version1.0 * /
 public class ChenPiMain {
 ​
   Exchanger<DataBuffer> exchanger = new Exchanger<DataBuffer>();
   DataBuffer initialEmptyBuffer = ... a made-up type
   DataBuffer initialFullBuffer = ...
 ​
   class FillingLoop implements Runnable {
 ​
     public void run(a) {
       DataBuffer currentBuffer = initialEmptyBuffer;
       try {
         while(currentBuffer ! =null) {
           addToBuffer(currentBuffer);
           if(currentBuffer.isFull()) { currentBuffer = exchanger.exchange(currentBuffer); }}}catch (InterruptedException ex) { ...handle ...}
     }
   }
 ​
   class EmptyingLoop implements Runnable {
 ​
     public void run(a) {
       DataBuffer currentBuffer = initialFullBuffer;
       try {
         while(currentBuffer ! =null) {
           takeFromBuffer(currentBuffer);
           if(currentBuffer.isEmpty()) { currentBuffer = exchanger.exchange(currentBuffer); }}}catch (InterruptedException ex) { ...handle ...}
     }
   }
 ​
   void start(a) {
     new Thread(new FillingLoop()).start();
     new Thread(newEmptyingLoop()).start(); }}Copy the code

This is the end of sharing ~~

If you think the article is helpful to you, like, favorites, follow, comment, your support is my creation