上个星期我到诚迈科技参加面试.面试完毕后面试官让我把笔试卷上的一道多线程题在计算机上编程实现.题目如下:
四个线程a,b,c,d. 线程a,b对变量i加一. 线程c,d对变量i减去一.四个线程顺序执行, 每个线程每次只执行一次.i的初始值为0, 打印结果0 1 2 1 0 1 2 1 0 1 2...
这道题还是有一定的难度的. 因为要求顺序执行. 不能简单用同步.
经考虑,我决定用一个队列来对四个线程顺序调度.代码如下:
package org.jenfer.struts2demo.web.struts2.action;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
* 四个线程a,b,c,d. 线程a,b对变量i加一.
* 线程c,d对变量i减去一.四个线程顺序执行,
* 每个线程每次只执行一次.i的初始值为0,
* 打印结果0 1 2 1 0 1 2 1 0 1 2...
*
* @author 武汉科技大学08级研究生周剑华
*
*/
public class MultiThreadTest {
//variable i
private int i=0;
//queue to control thread invoke
private BlockingQueue<Integer> queue=new LinkedBlockingQueue<Integer>();
public MultiThreadTest() {
queue.offer(1);
queue.offer(2);
queue.offer(3);
queue.offer(4);
}
public synchronized void inc(int con) throws InterruptedException{
while(true){
int c=queue.peek();
if(c==con){
break;
}else{
notifyAll();
wait();
}
}
queue.offer(queue.take());
i++;
System.out.println(Thread.currentThread().getName()+",i="+i);
}
public synchronized void dec(int con) throws InterruptedException{
while(true){
int c=queue.peek();
if(c==con){
break;
}else{
notifyAll();
wait();
}
}
queue.offer(queue.take());
i--;
System.out.println(Thread.currentThread().getName()+",i="+i);
}
private class IncThread implements Runnable{
private int condition;
public IncThread(int condition) {
this.condition=condition;
}
public void run() {
while(true){
try {
inc(condition);
} catch (InterruptedException e) {
System.err.println(Thread.currentThread().getName()+" exit now");
break;
}
}
}
}
private class DecThread implements Runnable{
private int condition;
public DecThread(int condition) {
this.condition=condition;
}
public void run() {
while(true){
try {
dec(condition);
} catch (InterruptedException e) {
System.err.println(Thread.currentThread().getName()+" exit now");
break;
}
}
}
}
public static void main(String[] args) {
MultiThreadTest test=new MultiThreadTest();
ExecutorService exec=Executors.newFixedThreadPool(4);
exec.submit(test.new IncThread(1));
exec.submit(test.new IncThread(2));
exec.submit(test.new DecThread(3));
exec.submit(test.new DecThread(4));
exec.shutdown();
}
}