题目是这样的:启动4个线程,第一个线程打印1,2;第二个线程打印3,4;第三个线程打印5,6;第四个线程打印7,8;然后第一个线程打印9,10...如此循环下去直到打印出100即终止.
刚拿到这个题目的时候,觉得好简单啊(眼高手低...),面试官要求直接把代码写在纸上,于是开始一顿猛如虎的操作,接下来就越来越尴尬了,首先脱离了编辑器差点线程池的创建的单词都拼错...然后写了一段自己都觉得Low的代码,虽然功能是实现了,但面试官看到并不满意,因为这道题他出题的意图应该是在考察jdk1.5 concurren包下的condition和signal方法,而我压根就没有用condition和signal,我误以为是要考察线程池和callable及future的知识,然后通过这种方式用了好几条if,实现的一点不优雅.直到最后出来坐在地铁上思考才恍然大悟,为啥不用condition呢?因为不想让犯过的错再犯第二遍,所以特写此篇总结一下.
首先需要创建一把悲观锁,然后需要为四个线程分别创建各自的condition.再定义全局的数值用于打印1-100,每次打印后自增,最后一样就是全局的condition控制器(用具体的数值来保证每次休眠和唤醒哪几个线程),废话不多说,还是直接上代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class T {
private Integer curNum = 1;
private Integer no = 1;
private final Lock lock = new ReentrantLock();
private final Condition condition1 = lock.newCondition();
private final Condition condition2 = lock.newCondition();
private final Condition condition3 = lock.newCondition();
private final Condition condition4 = lock.newCondition();
public void printNum() {
if (curNum > 100) {
Thread.currentThread().interrupt();
return;
}
for (int i = 0; i < 2; i++) {
System.out.println(Thread.currentThread().getName() + " : " + (curNum++));
}
}
public void process1() {
lock.lock();
try {
while (no != 1)
condition1.await();
printNum();
no = 2;
condition2.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void process2() {
lock.lock();
try {
while (no != 2)
condition2.await();
printNum();
no = 3;
condition3.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void process3() {
lock.lock();
try {
while (no != 3)
condition3.await();
printNum();
no = 4;
condition4.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void process4() {
lock.lock();
try {
while (no != 4)
condition4.await();
printNum();
no = 1;
condition1.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
final T t = new T();
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
t.process1();
}
}).start();
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
t.process2();
}
}).start();
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
t.process3();
}
}).start();
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
t.process4();
}
}).start();
}
}
结果完全符合预期: