Today to take a look at the interview of communication between threads, experienced the interview of all know, in addition to the algorithm, sorting, singleton mode is the test point of communication between threads. Come on, meow, meow.

1. Print two numbers alternately

1.1 Custom Locks

Use volatile to ensure data visibility and prevent multiple threads from accessing the same variable. Consider defining a volatile Boolean flag. If flag is true, thread 1 prints 1 and sets flag to false. If flag is false, thread 2 prints 2 and sets falg to true.

package cn.alibaba.thread; public class ThreadPrint2 { volatile static boolean flag=true; //volatile public static void main(String[] args) { Thread t1=new MyThread(1); Thread t2=new MyThread(2); t1.start(); t2.start(); } static class MyThread extends Thread { int printValue; public MyThread(int printValue) { this.printValue = printValue; } @Override public void run() { for (int i = 0; i < 5; i++) { if (flag) { System.out.println("1"); } else { System.out.println("2"); } flag = ! flag; }}}} 1234567891011121314151617181920212223242526272829303132Copy the code

1.2 wait/notify/notify All

/** * @author: xingkong * @date: 2020/10/8 15:11 * @description: */ public class ThreadPrinter implements Runnable { private final String name; private final Object prev; private final Object self; private ThreadPrinter(String name, Object prev, Object self) { this.name = name; this.prev = prev; this.self = self; } @override public void run() {while (true) { Synchronized (prev) {synchronized (self) {system.out.print (name); / / print self. NotifyAll (); // Wake up other threads to compete for the self lock, noting that the self lock is not immediately released. } // The synchronization block for self is completed, and the self lock is released. try { prev.wait(); /** * The JVM selects a random thread from the wait() thread for the object lock, assigns the object lock to it, wakes it up, and continues execution. */ } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws Exception { Object a = new Object(); Object b = new Object(); ThreadPrinter pa = new ThreadPrinter("A", b, a); ThreadPrinter pb = new ThreadPrinter("B", a, b); new Thread(pa).start(); Thread.sleep(10); New Thread(pb).start(); Thread.sleep(10); }} 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556Copy the code

1.3 ReentrantLock combines Condition

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ABC_Condition { private static Lock lock = new ReentrantLock(); private static Condition A = lock.newCondition(); private static Condition B = lock.newCondition(); private static int count = 0; static class ThreadA extends Thread { @Override public void run() { try { lock.lock(); for (int i = 0; i < 10; i++) { while (count % 2 ! A.wait (); a.wait () {count % 3 = 0; } system.out. print("A"); count++; B.signal(); }} Catch (InterruptedException e) {e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadB extends Thread { @Override public void run() { try { lock.lock(); for (int i = 0; i < 10; i++) { while (count % 2 ! = 1) { B.await(); } system.out.print ("B");} system.out.print ("B");} system.out.print ("B"); count++; A.signal(); }} Catch (InterruptedException e) {e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { new ThreadA().start(); new ThreadB().start(); }} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960Copy the code

1.4 Semaphore mode

/** * @author: xingkong * @date: 2020/10/8 15:34 * @description: */ import java.util.concurrent.Semaphore; public class MultipleThreadRotationUsingSemaphore { public static void main(String[] args) { PrintABCUsingSemaphore printABC = new PrintABCUsingSemaphore(); new Thread(() -> printABC.printA()).start(); new Thread(() -> printABC.printB()).start(); } } class PrintABCUsingSemaphore { private Semaphore semaPhoreA = new Semaphore(1); private Semaphore semaPhoreB = new Semaphore(0); //private int attempts = 0; public void printA() { print("A", semaPhoreA, semaPhoreB); } public void printB() { print("B", semaPhoreB, semaPhoreA); } private void print(String name, Semaphore currentSemaphore, Semaphore nextSemaphore) { while (true){ try { currentSemaphore.acquire(); System.out.println(Thread.currentThread().getName() +" print "+ name); nextSemaphore.release(); } catch (InterruptedException e) { e.printStackTrace(); }}}} 1234567891011121314151617181920212223242526272829303132333435363738394041Copy the code

2. Print ABC alternately

2.1 wait/notify/notify All

public static class ThreadPrinter implements Runnable { private String name; private Object prev; private Object self; private ThreadPrinter(String name, Object prev, Object self) { this.name = name; this.prev = prev; this.self = self; } @Override public void run() { int count = 10; While (count > 0) { Synchronized (prev) {synchronized (self) {system.out.print (name); / / print the count -; self.notifyAll(); // Wake up other threads to compete for the self lock, noting that the self lock is not immediately released. } // The synchronization block for self is completed, and the self lock is released. Try {if (count ==0) {// If count==0, this is the last print operation and notifyAll is used to release the lock. prev.notifyAll(); } else { prev.wait(); }} Catch (InterruptedException e) {e.printStackTrace(); } } } } } public static void main(String[] args) throws Exception { Object a = new Object(); Object b = new Object(); Object c = new Object(); ThreadPrinter pa = new ThreadPrinter("A", c, a); ThreadPrinter pb = new ThreadPrinter("B", a, b); ThreadPrinter pc = new ThreadPrinter("C", b, c); new Thread(pa).start(); Thread.sleep(10); New Thread(pb).start(); Thread.sleep(10); new Thread(pc).start(); Thread.sleep(10); } 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152Copy the code

It can be seen that the program defines three object locks, a, B, C, respectively corresponding to a, B, C three threads.

Thread A runs first. Thread A applies for locks on objects C and A in sequence, releases locks on objects A and C in sequence after printing, and wakes up thread B through notify.

Thread B first waits for lock A, then applies for lock B, prints lock B, releases lock B, and wakes up lock C.

Thread C waits for lock B, applies for lock C, prints lock C, releases lock C, and wakes up lock A.

The initial condition is that three threads must be started in order A,B, and C, but this assumption depends on the order in which threads are scheduled and executed in the JVM.

“Pictures from the Internet, infringement deleted”

2.2 ReentrantLock combines Condition

The common way to work with ReentrantLock is Condition, which is bound to Lock and must be created using lock.newcondition (). As can be seen from the above code, Condition can realize all the communication modes realized by Synchronized, and codes with similar functions are written in the same line.

import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ABC_Condition { private static Lock lock = new ReentrantLock(); private static Condition A = lock.newCondition(); private static Condition B = lock.newCondition(); private static Condition C = lock.newCondition(); private static int count = 0; static class ThreadA extends Thread { @Override public void run() { try { lock.lock(); for (int i = 0; i < 10; i++) { while (count % 3 ! A.wait (); a.wait () {count % 3 = 0; } system.out. print("A"); count++; B.signal(); }} Catch (InterruptedException e) {e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadB extends Thread { @Override public void run() { try { lock.lock(); for (int i = 0; i < 10; i++) { while (count % 3 ! = 1) { B.await(); } system.out.print ("B");} system.out.print ("B");} system.out.print ("B"); count++; C.signal(); }} Catch (InterruptedException e) {e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadC extends Thread { @Override public void run() { try { lock.lock(); for (int i = 0; i < 10; i++) { while (count % 3 ! = 2) { C.await(); } system.out. print("C"); count++; A.signal(); }} Catch (InterruptedException e) {e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); }} 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646 566676869707172737475767778798081828384Copy the code

2.3 Semaphore mode

Semaphore, also known as Semaphore, is an operating system concept that controls the number of concurrent threads in Java concurrent programming.

Public Semaphore(int permitting) permitting indicates the number of threads running concurrently.

Semaphore is used to protect access to one or more shared resources. Semaphore maintains an internal counter for the number of shared resources that can be accessed. To access a shared resource, a thread obtains a semaphore first. If the semaphore’s counter value is greater than 1, which indicates that a shared resource is available to access, the thread reduces its counter value by 1 before accessing the shared resource. If the counter value is 0, the thread goes to sleep. When a thread runs out of shared resources, it releases the semaphore and increments the counter inside the semaphore by one. The thread that went to sleep will wake up and try to acquire the semaphore again.

Before using a Semaphore, you need to construct a parameter to specify the number of shared resources. After the Semaphore construction is complete, the Semaphore is obtained and the shared resources are released.

import java.util.concurrent.Semaphore; Private static Semaphore A = new Semaphore(1); private static Semaphore A = new Semaphore(1); Private static Semaphore B = new Semaphore(0); private static Semaphore B = new Semaphore(0); private static Semaphore C = new Semaphore(0); static class ThreadA extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { A.acquire(); System.out.print("A"); B.release(); If (InterruptedException e) {e.printStacktrace (); if (InterruptedException e) {e.printstacktrace (); } } } static class ThreadB extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { B.acquire(); System.out.print("B"); C.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadC extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { C.acquire(); System.out.println("C"); A.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); }} 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162Copy the code

2.4 LockSupport

import java.util.concurrent.locks.LockSupport; /** * @author: xingkong * @date: 2020/10/8 15:45 * @description: */ public class LockSupportDemo1 { static Thread t1 = null; static Thread t2 = null; public static void main(String[] args) { t1 = new Thread(() -> { for (int i = 65; i < 91; i++) { System.out.print((char) i); LockSupport.unpark(t2); LockSupport.park(); }}); t2 = new Thread(() -> { for (int i = 1; i < 27; i++) { LockSupport.park(); System.out.print(i); LockSupport.unpark(t1); }}); t1.start(); t2.start(); }} 12345678910111213141516171819202122232425262728293031Copy the code

Finally, make sure you know how each of these works, and try it out for yourself. After understanding the interview can confidently write out. The moment you write it, you are one step closer to the offer. Come on. Working for a dream.

Please pay attention to the public number “programmer interview way” reply to “interview” to get a complete set of interview package!!

Recommendation of high quality articles

1. Computer network —- Three times handshake four times wave 2. An article that gives you a thorough understanding of the structure of HTTP request and response packets 3. A dream come true —– project self-introduction 4. An article that lets you thoroughly understand the past life of HTTP 5. An article that will get you through HTTP methods and status codes 6. Here’s your design pattern 7. Shock!!! Check out this programmer interview manual!! 9. Nearly 30 interviews shared