现在的位置: 首页 > 综合 > 正文

线程协作测试

2013年10月26日 ⁄ 综合 ⁄ 共 2494字 ⁄ 字号 评论关闭
文章目录

题目来自今年某公司一次笔试试题。

大致题目要求为:

一个线程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");
    }

抱歉!评论已关闭.