Summary of some methods of communication between java threads

  • 2021-08-16 23:51:50
  • OfStack

Preface

In concurrent programming, we may encounter such a scenario

The A and B threads are parallel, but I want to ensure that the B thread is executed after the A thread has finished executing

This is when threads need to communicate

After A is executed, say 1 to B, feed B, I am finished

How to realize Java in Kangkang

1. Based on synchronized

2. Based on reentrantLock

3. Based on volatile

4. Based on countDownLatch

I know these four kinds at present

1. synchronized+wait () and notify ()

wait () and notify () are communication methods of Object class. Note 1: wait and notify must be used with synchronized, and wait () releases the lock, while notify () does not release the lock


public class SynchronizedTest {

 // Define a year Used to record the number of years a star has practiced 
 private static double year;

 public void run() {
  // Thread A Practice singing and dancing rap
  Thread threadA = new Thread(() -> {
   synchronized (this) {
    for (year = 0.5; year <= 5; year += 0.5) {
     System.out.println(" Cai Xuji began to practice singing and dancing rap : Practiced " + year + " Year ");
     try {
      Thread.sleep(288);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     // As we all know, you can make your debut after two and a half years of practice 
     if (year == 2.5) {
      System.out.println("===========================> Successful practice for two and a half years, debut! ! ! ");
      this.notify();
     }
    }
   }
  });
  // Thread B Practice playing basketball 
  Thread threadB = new Thread(() -> {
   while (true) {
    synchronized (this) {
     try {
      this.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println(" Cai Xuji began to practice playing basketball ");
    }
   }
  });
  // Attention, 1 Be sure to start first B , or it will lead to B Never get the lock 
  threadB.start();
  threadA.start();
 }

 public static void main(String[] args) {
  SynchronizedTest test = new SynchronizedTest();
  test.run();
 }
}

Run results:

Cai Xuji began to practice singing and dancing rap: He has practiced for 0.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 2.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 2.5 years
=========================== > Successful practice for two and a half years, debut! ! !
Cai Xuji began to practice singing and dancing rap: He has practiced for 3.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 3.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.5 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 5.0 years
Cai Xuji began to practice playing basketball

Note that the thread A does not release the lock after executing notify, but starts executing the task of thread B after executing the current task

2. Based on ReentrantLock

ReentrantLock can also realize inter-thread communication, but it is a bit troublesome, so it needs to be combined with Condition of ReentrantLock


public class LockTest {
  // Define a year Used to record the number of years a star has practiced playing basketball 
  private static double year;

  public static void main(String[] args) {
   ReentrantLock lock = new ReentrantLock();
   Condition condition = lock.newCondition();
   // Thread A Practice singing and dancing rap
   Thread threadA = new Thread(() -> {
    // Lock before executing business code 
    lock.lock();
    for (year = 0.5; year <= 5; year += 0.5) {
     System.out.println(" Cai Xuji began to practice singing and dancing rap : Practiced " + year + " Year ");
     try {
      Thread.sleep(288);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     // As we all know, you can make your debut after two and a half years of practice 
     if (year == 2.5) {
      System.out.println("===========================> Successful practice for two and a half years, debut! ! ! ");
      // Wake up a waiting thread 
      condition.signal();
     }
    }
    // Unlock after business code execution 
    lock.unlock();
   });
   // Thread B Practice playing basketball 
   Thread threadB = new Thread(() -> {
    // Lock before executing business code 
    lock.lock();
    while (true) {
     try {
      // Let the thread wait if the counter is 0 If so, it will be executed immediately 
      condition.await();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println(" Cai Xu's old hen began to practice playing basketball ");
     break;
    }
    // Unlock after business code execution 
    lock.unlock();
   });
   // Attention, 1 Be sure to start first B , or it will lead to B Never get the lock 
   threadB.start();
   threadA.start();
  }
 }

Run results:

Cai Xuji began to practice singing and dancing rap: He has practiced for 0.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 2.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 2.5 years
=========================== > Successful practice for two and a half years, debut! ! !
Cai Xuji began to practice singing and dancing rap: He has practiced for 3.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 3.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.5 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 5.0 years
Cai Xu's old hen began to practice playing basketball

The effect was similar to that of synchronized+wait () and notify ()

3. Based on volatile

The use of shared variables can also be achieved, with volatile can, the principle is that multiple threads common monitoring of the same variable, according to the value of the variable changes to execute the corresponding task, here volatile is to let other threads can instantly perceive the value of the variable changes


public class volatileTest {
 // Definition 1 Shared variables, note that you must use volatile Modify 
 static volatile boolean flag = false;
 // Define a year Used to record the number of years a star has practiced playing basketball 
 private static double year;

 public static void main(String[] args) {
  // Thread A Practice singing and dancing rap
  Thread threadA = new Thread(() -> {
   while (true) {
    if (!flag) {
     for (year = 0.5; year <= 5; year += 0.5) {
      System.out.println(" Cai Xuji began to practice singing and dancing rap : Practiced " + year + " Year ");
      try {
       Thread.sleep(288);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      // As we all know, you can make your debut after two and a half years of practice 
      if (year == 2.5) {
       System.out.println("===========================> Successful practice for two and a half years, debut! ! ! ");
       year = 0.5;
       flag = true;
       break;
      }
     }
    }
   }
  });
  // Thread B Practice playing basketball 
  Thread threadB = new Thread(() -> {
   while (true) {
    if (flag) {
     System.out.println(" Cai Xu's old hen began to practice playing basketball ");
     break;
    }
   }
  });
  // Startup thread 
  threadA.start();
  threadB.start();
 }
}

Run results:

Cai Xuji began to practice singing and dancing rap: He has practiced for 0.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 1.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 2.0 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 2.5 years
=========================== > Successful practice for two and a half years, debut! ! !
Cai Xu's old hen began to practice playing basketball

Based on CountDownLatch

CountDownLatch is a concurrent programming tool under JUC package, which mainly has two methods, countDown and await. CountDownLatch maintains a counter at the bottom, which is set at the time of instantiation. When calling countDown method, the counter is minus 1. If the counter is 0 before minus 1, nothing will happen. If it becomes 0 after minus 1, it will wake up all waiting threads; The await method causes the current thread to wait until the counter is 0


public class CountDownLatchTest {
 // Define a year Used to record the number of years a star has practiced playing basketball 
 private static double year;

 public static void main(String[] args) {
  CountDownLatch latch = new CountDownLatch(1);
  // Thread A Practice singing and dancing rap
  Thread threadA = new Thread(() -> {
   for (year = 0.5; year <= 5; year += 0.5) {
    System.out.println(" Cai Xuji began to practice singing and dancing rap : Practiced " + year + " Year ");
    try {
     Thread.sleep(288);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    // As we all know, you can make your debut after two and a half years of practice 
    if (year == 2.5) {
     System.out.println("===========================> Successful practice for two and a half years, debut! ! ! ");
     // Counter minus 1
     latch.countDown();
    }
   }
  });
  // Thread B Practice playing basketball 
  Thread threadB = new Thread(() -> {
   while (true) {
    try {
     // Let the thread wait if the counter is 0 If so, it will be executed immediately 
     latch.await();
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    System.out.println(" Cai Xu's old hen began to practice playing basketball ");
    break;
   }
  });
  // Startup thread 
  threadA.start();
  threadB.start();
 }
}

Run results:

Cai Xuji began to practice singing and dancing rap: He has practiced for 0.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 1.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 2.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 2.5 years
=========================== > Successful practice for two and a half years, debut! ! !
Cai Xuji began to practice singing and dancing rap: He has practiced for 3.0 years
Cai Xu's old hen began to practice playing basketball
Cai Xuji began to practice singing and dancing rap: he has practiced for 3.5 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.0 years
Cai Xuji began to practice singing and dancing rap: He has practiced for 4.5 years
Cai Xuji began to practice singing and dancing rap: he has practiced for 5.0 years

If you run it several times, you will find that the execution timing of thread B is random, but it will always start after the counter is 0, that is to say, after the counter is 0, whoever grabs the lock of thread A and thread B will execute

In this paper, all demo can be copied and run. Everyone still needs to do more work. If you have conditions at home, you can run 1 run with idea. If you have no conditions, you can copy it by hand

Summarize


Related articles: