总结秋招和实习面试的时候碰到的几个手撕的多线程代码题:
问题一:三个线程循环打印ABC,线程一打印A,线程二打印B,线程三打印C,打印10遍即可。这个问题主要是考察怎么使用线程同步的问题,通常情况下我们有多种解法,可以使用Condition,Synchronize,semaphore等等,我们用可重入锁来解答这个问题。(美团实习)
package com.test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author 红字V
* Created on 2021-08-19
* @description:多线程面试题
*/
public class PrintABC {
private int flag = 1;
Lock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
public void printA(){
lock.lock();
try {
while(flag != 1){
conditionA.await();
}
System.out.print("A");
conditionB.signal();
flag = 2;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printB(){
lock.lock();
try {
while(flag != 2){
conditionB.await();
}
System.out.print("B");
conditionC.signal();
flag = 3;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printC(){
lock.lock();
try {
while(flag != 3){
conditionC.await();
}
System.out.println("C");
conditionA.signal();
flag = 1;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
PrintABC printABC = new PrintABC();
Thread thread1 = new Thread(()->{
for(int i = 0; i<10;i++) printABC.printA();
});
Thread thread2 = new Thread(()->{
for(int i = 0; i<10;i++) printABC.printB();
});
Thread thread3 = new Thread(()->{
for(int i = 0; i<10;i++) printABC.printC();
});
thread1.start();
thread2.start();
thread3.start();
}
}
问题二:两个线程循环打印1-100,线程1打印奇数,线程2打印偶数(拼多多实习面试),其实我们解决了上面那个问题,这个问题易如反掌,只是稍微变形一下,你不妨自己尝试先写写然后再看答案。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author 红字V
* Created on 2021-08-19
* @description:print odd and even via two threads
*/
public class PrintOddAndEven {
private static int flag = 1;
Lock lock = new ReentrantLock();
Condition conditionEven = lock.newCondition();
Condition conditionOdd = lock.newCondition();
public void printEven(){
lock.lock();
try {
while(flag % 2 != 0){
conditionEven.await();
}
System.out.print(flag+" ");
conditionOdd.signal();
flag ++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void printOdd(){
lock.lock();
try {
while(flag % 2 != 1){
conditionOdd.await();
}
System.out.print(flag+" ");
conditionEven.signal();
flag ++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
PrintOddAndEven printOddAndEven = new PrintOddAndEven();
Thread thread1 = new Thread(()->{
while (flag < 100) printOddAndEven.printEven();
});
Thread thread2 = new Thread(()->{
while (flag < 100) printOddAndEven.printOdd();
});
thread1.start();
thread2.start();
}
}
问题三:阻塞队列,线程池的实现(滴滴实习),见我的这篇文章。