题目来自今年某公司一次笔试试题。
大致题目要求为:
一个线程A及一组线程B,令线程A触发B线程执行后进行等待,待线程B全部执行完毕后,A继续执行,求方案。
最简单的用wait/notify:
/**
* 线程A
*/
import java.util.ArrayList;
import java.util.Iterator;
public class ThreadA implements Runnable {
private ArrayList<Runnable> threadbs;
public void run() {
System.out.println("ThreadA start");
threadbs = new ArrayList<Runnable>();
for(int i = 0;i<10;i++) {
threadbs.add(new ThreadB(this));
}
Iterator<Runnable> iterator = threadbs.iterator();
while(iterator.hasNext()) {
motiveThreadB(iterator.next());
}
synchronized(this) {
try {
System.out.println("ThreadA starting to wait");
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("ThreadB all seem to be ended");
}
public void motiveThreadB(Runnable r) {
new Thread(r).start();
}
}
/**
* 线程B
*/
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadB implements Runnable {
private ThreadA ta;
private static int id = 0;
private int seq ;
private static AtomicInteger counter = new AtomicInteger(0);
public ThreadB(ThreadA t) {
this.ta = t;
seq = id++;
}
@Override
public void run() {
System.out.println("ThreadB "+seq+"started");
counter.addAndGet(1);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("ThreadB "+seq+"ended");
if(counter.decrementAndGet()==0) {
synchronized(ta) {
ta.notify();
}
}
}
}
/**
*驱动测试代码
*/
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestDriver {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new ThreadA());
exec.shutdown();
}
}
方案二:使用容量为1的阻塞队列,将wait和notify操作改为对队列的阻塞操作。
/*
* 线程A
*/
public class ThreadA implements Runnable{
LinkedBlockingQueue<String> bq = new LinkedBlockingQueue<String>(1);
public void run() {
ArrayList<Runnable> threadbs = new ArrayList<Runnable>();
System.out.println("init bq");
for(int i = 0;i<10;i++) {
threadbs.add(new ThreadB(this));
}
Iterator<Runnable> iterator = threadbs.iterator();
while(iterator.hasNext()) {
new Thread(iterator.next()).start();
}
System.out.println("try to blocked insert element");
try {
bq.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Added element successfully");
System.out.println("ThreadB all seem to be ended");
}
}
/**
* 线程B的关键代码
*/
public void run() {
System.out.println("Thread+"+seq+"started");
counter.addAndGet(1);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(counter.decrementAndGet()==0) {
System.out.println("Thread+"+seq+"removeded element"+ta.bq.add("c"));
}
System.out.println("Thread+"+seq+"ended");
}