文章目录
题目来自今年某公司一次笔试试题。
大致题目要求为:
一个线程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"); }