How do two threads execute alternately, one even and one odd?

Author: Mona Rudow
cnblogs.com/stateis0/p/9091254.html

It is interesting for the landlord to see this topic on the face canvas today. Small topics also have a lot of consideration for multi-threading.Most students will use synchronized to achieve.

The landlord today brings two other optimization implementations, so that you can be arrogant when interviewing!

synchronized implementation

class ThreadPrintDemo2 {
  public static void main(String[] args) {
    final ThreadPrintDemo2 demo2 = new ThreadPrintDemo2();
    Thread t1 = new Thread(demo2::print1);
    Thread t2 = new Thread(demo2::print2);

    t1.start();
    t2.start();
  }

  public synchronized void print2() {
    for (int i = 1; i <= 100; i += 2) {
      System.out.println(i);
      this.notify();
      try {
        this.wait();
        Thread.sleep(100);
      } catch (InterruptedException e) {

      }
    }
  }

  public synchronized void print1() {
    for (int i = 0; i <= 100; i += 2) {
      System.out.println(i);
      this.notify();
      try {
        this.wait();
        Thread.sleep(100);
      } catch (InterruptedException e) {

      }
    }
  }
}

Through synchronized synchronization, only one thread can enter at a time, and each number printed, the lock is released, another thread enters, gets the lock, prints, wakes another thread, and suspends itself.Loop and repeat, to achieve a basic printing function.Interviews often ask: Synchronized has several uses.

But if you do, the interviewer is certainly dissatisfied.The landowner will introduce a better implementation.

CAS implementation

public class ThreadPrintDemo {

  static AtomicInteger cxsNum = new AtomicInteger(0);
  static volatile boolean flag = false;

  public static void main(String[] args) {

    Thread t1 = new Thread(() -> {
      for (; 100 > cxsNum.get(); ) {
        if (!flag && (cxsNum.get() == 0 || cxsNum.incrementAndGet() % 2 == 0)) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {

          }

          System.out.println(cxsNum.get());
          flag = true;
        }
      }
    }
    );

    Thread t2 = new Thread(() -> {
      for (; 100 > cxsNum.get(); ) {
        if (flag && (cxsNum.incrementAndGet() % 2 != 0)) {
          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {

          }

          System.out.println(cxsNum.get());
          flag = false;
        }
      }
    }
    );

    t1.start();
    t2.start();
  }
}

We avoided thread context switching by using CAS, and then, using a volatile boolean variable guaranteed no visibility issues. Remember, this flag must be volatile. If not, your program might work fine, but eventually it will, and the interviewer will immediately despise you.Interviews often ask: Deep understanding of CAS algorithm principles.

This eliminates the loss of context switching caused by the use of synchronized and results in better performance.Believe that if you do this during an interview, the interviewer will be satisfied.

But we still have better performance.

volatile implementation

class ThreadPrintDemo3{

  static volatile int num = 0;
  static volatile boolean flag = false;

  public static void main(String[] args) {

    Thread t1 = new Thread(() -> {
      for (; 100 > num; ) {
        if (!flag && (num == 0 || ++num % 2 == 0)) {

          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {

          }

          System.out.println(num);
          flag = true;
        }
      }
    }
    );

    Thread t2 = new Thread(() -> {
      for (; 100 > num; ) {
        if (flag && (++num % 2 != 0)) {

          try {
            Thread.sleep(100);
          } catch (InterruptedException e) {

          }

          System.out.println(num);
          flag = false;
        }
      }
    }
    );

    t1.start();
    t2.start();

  }
}

We use volatile Variables replace CAS variables to reduce the consumption of CAS. Note that +num is not atomic here, but it does not interfere because there is flag variable control.Num must be volatile, and if not, it can cause visibility problems.

Here, if you write this during an interview, then offer is not far away!Ha-ha!!

Egg: How do I flip the string?

class ReverseDemo {

  public static void main(String[] args) {

    String test = "abcdefg";

    System.out.println(new StringBuilder(test).reverse());

    char[] arr = test.toCharArray();

    for (int i = arr.length - 1; i >= 0; i--) {
      System.out.print(arr[i]);
    }

  }
}

This is easier. There are two ways, one is StringBuilder's reverse method, the other is to convert to an array to print on its own.The self-conversion performance is better, and the reverse method has more internal steps.

Well, I hope you all have a successful interview!!

Recommend going to my blog to read more:

1.Java JVM, Collections, Multithreaded, New Features Series Tutorial

2.Spring MVC, Spring Boot, Spring Cloud series tutorials

3.Maven, Git, Eclipse, Intellij IDEA Series Tools Tutorial

4.Latest Interview Questions for Java, Backend, Architecture, Alibaba, etc.

Feel good, don't forget to say yes + forward!

Tags: Java Spring jvm Maven

Posted on Mon, 11 May 2020 22:57:13 -0400 by tamilmani