纯贴拒绝无意义灌水:顶、学习、JF……之类的垃圾回复
(JDK1.5+)在多线程中,我们要得到子线程的结果一般就使用callable接口,用future来获取子线程的返回值。那么在试验中发现如果用了callable接口,那子线程中的操作好像都变成了“串行”?这是怎么回事?如果变成了串行,那我多线程还有什么意义??有没有高手来解答一下?具体举个事例如下:10个人百米赛跑,裁判开枪10个人同时起跑,最后一个人跑完100米,比赛结束。那么在这个事例中,10个人就是10个子线程,每个线程干的事就是跑完100米。主线程要获取最后一个线程跑完100米的时间,然后主线程结束。测试代码:public abstract class FutureProxy{    private final class CallableImpl implements Callable{        public Object call() throws Exception {
            return FutureProxy.this.createInstance();
        }
    }
    private static class InvocationHandlerImpl implements InvocationHandler {        private Future future;
        
        private volatile Object instance;
        
        InvocationHandlerImpl(Future future){
            this.future = future;
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            synchronized(this){
                if(this.future.isDone()){
                    this.instance = this.future.get();
                }else{
                    while(!this.future.isDone()){
                        try{
                            this.instance = this.future.get();
                        }catch(InterruptedException e){
                            Thread.currentThread().interrupt();
                        }
                    }
                }
                
                return method.invoke(this.instance, args);
            }
        }
    }    private static final class ThreadFactoryImpl implements ThreadFactory {        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setDaemon(true);
            return thread;
        }
    }    private static ExecutorService service = Executors.newCachedThreadPool(new ThreadFactoryImpl());    protected abstract Object createInstance();    protected abstract Class getInterface();
    public final Object getProxyInstance() {
        Class interfaceClass = this.getInterface();
        if (interfaceClass == null || !interfaceClass.isInterface()) {
            throw new IllegalStateException();
        }        Callable task = new CallableImpl();        Future future = FutureProxy.service.submit(task);        return (Object) Proxy.newProxyInstance(interfaceClass.getClassLoader(),
                new Class[] { interfaceClass }, new InvocationHandlerImpl(future));
    }
}
interface DateTest{    String getDate();
} class DateTestImpl implements DateTest{
    
    private String _date=null;
     
    public DateTestImpl(){
        try{
            _date+=Calendar.getInstance().getTime();
           }catch(Exception e){
        }
    }
    
    public String getDate() {
//A.method是一个费时操作,比如读取数据库之类的……
    A a=new A();
    String s="";
    if(a.method()){
    s="a:"+Calendar.getInstance().getTime();
     }else{
     s="b:"+Calendar.getInstance().getTime();
     }
        return "date "+_date+":"+s;
    }
} class DateTestFactory extends FutureProxy{    protected Object createInstance() {
        return new DateTestImpl();
    }    
    protected Class getInterface() {
        return DateTest.class;
    }
}public class Test{    public  static void main(String[] args) {
    
        DateTestFactory factory = new DateTestFactory();
        DateTest[] dts = new DateTest[10];
        for(int i=0;i<dts.length;i++){
            dts[i]=(DateTest)factory.getProxyInstance();
        }
        for(int i=0;i<dts.length;i++){
            System.out.println(dts[i].getDate());
        }
        
    }
}
在示例代码中运行发现,A.method是我想用多线程(循环顺序执行浪费时间为了节省时间使用多线程)执行的一个操作,可打出来的结果发现s值时间是顺序的:Tue Jul 07 10:35:20 CST 2009
Tue Jul 07 10:35:25 CST 2009
Tue Jul 07 10:35:30 CST 2009
高手解答下为什么会这样?那我为了节省时间使用多线程该怎么办?

解决方案 »

  1.   

    郁闷公司机器只有jre1.4没法测,找了一个例子,LZ测试看看有没有什么问题~import java.util.*;
    import java.util.concurrent.*;public class CallableExample {    public static class WordLengthCallable
                implements Callable {
            private String word;
            public WordLengthCallable(String word) {
                this.word = word;
            }
            public Integer call() {
                return Integer.valueOf(word.length());
            }
        }    public static void main(String args[]) throws Exception {
            ExecutorService pool = Executors.newFixedThreadPool(3);
            Set<Future<Integer>> set = new HashSet<Future&lg;Integer>>();
            for (String word: args) {
                Callable<Integer> callable = new WordLengthCallable(word);
                Future<Integer> future = pool.submit(callable);
                set.add(future);
            }
            int sum = 0;
            for (Future<Integer> future : set) {
                sum += future.get();
            }
            System.out.printf("The sum of lengths is %s%n", sum);
            System.exit(sum);
        }
    }
      

  2.   

    在你的程序中,DateTestImpl的getDate()方法都是在主线程中被调用的。子线程的工作只是创建DateTest实例。打印出的时间也不是子线程结束的时间。