练手——蚂蚁二面笔试题
1. 起两个线程,交替打印奇数和偶数
一拿到这个题目有几个思路,1.共享变量,2.等待/通知机制,其实感觉考察的是进程通信的方式(6种)
共享变量实现如下:
public class oddAndEvenPrintThread {
public static int cnt = 0;
public static final int RANGE = 1000;
public static List<Integer> ans = new ArrayList<>(RANGE);
public static void main(String[] argus) {
Thread oddPrinter = new Thread(() -> {
while (cnt < RANGE) {
if ((cnt & 1) == 1) {
//System.out.println(cnt);
ans.add(cnt);
cnt++;
}
}
}, "oddPrinter");
Thread evenPrinter = new Thread(() -> {
while (cnt < RANGE) {
if ((cnt & 1) == 0) {
//System.out.println(cnt);
ans.add(cnt);
cnt++;
}
}
}, "evenPrinter");
try {
oddPrinter.start();
evenPrinter.start();
oddPrinter.join();
evenPrinter.join();
} catch (Exception e) {
e.printStackTrace();
}
ans.forEach((a) -> System.out.print(a + " "));
}
}
其实这里可以有几个优化的地方,1.用线程池代替单独的线程;2.当不满足cnt条件时可以加一个yield主动放弃cpu资源(这个见仁见智,我觉得没必要,多核cpu还会增加上下文切换的开销)
用线程池又写了一个版本:(此处如果面试还能再阐述下线程池的几个好处,绝对的加分项)
public class oddAndEvenPrintThread {
public static int cnt = 0;
public static final int RANGE = 1000;
public static List<Integer> ans = new ArrayList<>(RANGE);
public static final ExecutorService oddExecutorService = new ThreadPoolExecutor(1,1,60L, TimeUnit.SECONDS,new LinkedBlockingQueue<>());
public static final ExecutorService even