Google面试题—有四个线程1、2、3、4。线程1的功能就是输出1,线程2的功能就是输出2,以此类推.........现在有四个文件ABCD
程序运行起来,4个文件的写入结果如下:
A:12341234...
B:23412341...
C:34123412...
D:41234123...
同学给我出了道面试题,自己首先想到的是用信号灯,感觉自己应该理解错了。不可能这么简单。
java1.5以前的手法写了一个,感觉不对,后来发觉应该是斜向输出。这道题大概主要是考察对多线程的流程控制。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class CallThread {
private static class MyRunable implements Runnable {
int index = 0;
int max = 4 * 2;
HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
{
for (int i = 0; i < 4; i++) {
map.put(i, new ArrayList<Integer>());
}
}
boolean isRunning = true;
public synchronized void run() {
while (true) {
int name = Integer.valueOf(Thread.currentThread().getName());
while (index % 4 != name) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRunning) {
return;
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
for (int i = 0, arrIndex = index; i < 4; i++ ) {
try {
if (arrIndex-- < 0) {
break;
}
List<Integer> list = map.get(i);
if (list.size() < max) {
list.add(name + 1);
}
} catch (Exception e) {
}
}
System.err.println("A:" + map.get(0));
System.err.println("B:" + map.get(1));
System.err.println("C:" + map.get(2));
System.err.println("D:" + map.get(3));
System.err.println("-----------------------");
if (map.get(map.size()-1).size() == max) {
isRunning = false;
this.notifyAll();
return;
} else {
index++;
}
this.notifyAll();
}
}
}
public static void main(String[] args) throws InterruptedException {
Runnable runable = new MyRunable();
for (int i = 0; i < 4; i++) {
Thread t = new Thread(runable);
t.setName(String.valueOf(i));
t.start();
}
}
}
程序打印结果
A:[1]
B:[]
C:[]
D:[]
-----------------------
A:[1, 2]
B:[2]
C:[]
D:[]
-----------------------
A:[1, 2, 3]
B:[2, 3]
C:[3]
D:[]
-----------------------
A:[1, 2, 3, 4]
B:[2, 3, 4]
C:[3, 4]
D:[4]
-----------------------
A:[1, 2, 3, 4, 1]
B:[2, 3, 4, 1]
C:[3, 4, 1]
D:[4, 1]
-----------------------
A:[1, 2, 3, 4, 1, 2]
B:[2, 3, 4, 1, 2]
C:[3, 4, 1, 2]
D:[4, 1, 2]
-----------------------
A:[1, 2, 3, 4, 1, 2, 3]
B:[2, 3, 4, 1, 2, 3]
C:[3, 4, 1, 2, 3]
D:[4, 1, 2, 3]
-----------------------
A:[1, 2, 3, 4, 1, 2, 3, 4]
B:[2, 3, 4, 1, 2, 3, 4]
C:[3, 4, 1, 2, 3, 4]
D:[4, 1, 2, 3, 4]
-----------------------
A:[1, 2, 3, 4, 1, 2, 3, 4]
B:[2, 3, 4, 1, 2, 3, 4, 1]
C:[3, 4, 1, 2, 3, 4, 1]
D:[4, 1, 2, 3, 4, 1]
-----------------------
A:[1, 2, 3, 4, 1, 2, 3, 4]
B:[2, 3, 4, 1, 2, 3, 4, 1]
C:[3, 4, 1, 2, 3, 4, 1, 2]
D:[4, 1, 2, 3, 4, 1, 2]
-----------------------
A:[1, 2, 3, 4, 1, 2, 3, 4]
B:[2, 3, 4, 1, 2, 3, 4, 1]
C:[3, 4, 1, 2, 3, 4, 1, 2]
D:[4, 1, 2, 3, 4, 1, 2, 3]
-----------------------
jdk1.5写法
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class CallThread2 {
static int index = 0;
static int max = 4 * 2;
static HashMap<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
static {
for (int i = 0; i < 4; i++) {
map.put(i, new ArrayList<Integer>());
}
}
static boolean isRunning = true;
public static class MyRunnable implements Runnable {
int name;
Lock lock;
Condition condition;
private MyRunnable(int name, Lock lock, Condition condition) {
super();
this.name = name;
this.lock = lock;
this.condition = condition;
}
public boolean isMyName(int index) {
while (index != name) {
myWait();
if(!isRunning)return false;
return true;
}
return false;
}
public void myWait() {
lock.lock();
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
}
public void myNotifyAll() {
lock.lock();
condition.signalAll();
lock.unlock();
}
@Override
public void run() {
// TODO Auto-generated method stub
while (isRunning) {
while (isMyName(index % 4)) {
}
if(!isRunning)return;
for (int i = 0, arrIndex = index; i < 4; i++) {
try {
if (arrIndex-- < 0) {
break;
}
List<Integer> list = map.get(i);
if (list.size() < max) {
list.add(name + 1);
}
} catch (Exception e) {
}
}
System.err.println("A:" + map.get(0));
System.err.println("B:" + map.get(1));
System.err.println("C:" + map.get(2));
System.err.println("D:" + map.get(3));
System.err.println("-----------------------");
if (map.get(map.size() - 1).size() == max) {
isRunning = false;
myNotifyAll();
return;
} else {
index++;
}
myNotifyAll();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 4; i++) {
threadPool.execute(new MyRunnable(i, lock, condition));
}
threadPool.shutdown();
}
}
感觉自己应该理解错了。不可能这么简单。