本帖最后由 zlyperson 于 2011-02-05 23:43:44 编辑

解决方案 »

  1.   

    线程同步,很简单,google下吧。兄弟。
      

  2.   

    这是第二个帖子了吧?问题描述得还是让人看不懂!1、为什么 “pool-1-thread-1” 线程里面输出的Thread是Main而不是Thread-1的名字呢?
    如输出“getV:pool-1-thread-1 [Thread:main i=0 j=0 ]”你说的是红色的部分么?方括号部分 [Thread:main i=0 j=0 ] 是在这里设置的:threadPool.execute(new ThreadPoolTask(" [Thread:"
        + Thread.currentThread().getName() + " i=" + i + " j="
        + j + " " + "] "));而这里的 Thread.currentThread() 获得的是主线程,因为并不是在 Task 的 run 方法中的代码。问题二:由于线程池你设定的最大数量是 1,ArrayBlockingQueue 的大小是 1,如果当前有线程没有运行完,且又有新的任务来临时,会执行 RejectedExecutionHandler#rejectedExecution 方法,你设定的拒绝策略是 ThreadPoolExecutor.CallerRunsPolicy。因此,任务不会采用异步方式执行,而是直接调用了 run 方法采取同步执行的方式。第三个问题:这种需要采取不同的同步器,实现方式在 JDK 5 新增的并发包中有很多种,常用的有:CountDownLatch(倒计数门闩)、CyclicBarrier(循环障栅)、Semaphore(信号量)等。你这里适合使用前两种,最适合使用第二个 CyclicBarrier
      

  3.   


    问题二:由于线程池你设定的最大数量是 1,ArrayBlockingQueue 的大小是 1,如果当前有线程没有运行完,且又有新的任务来临时,会执行 RejectedExecutionHandler#rejectedExecution 方法,你设定的拒绝策略是 ThreadPoolExecutor.CallerRunsPolicy。因此,任务不会采用异步方式执行,而是直接调用了 run 方法采取同步执行的方式。红色部分的意思是不是说。如果线程池的线程在忙新的任务就交给主线程了啊?
    第三个问题:这种需要采取不同的同步器,实现方式在 JDK 5 新增的并发包中有很多种,常用的有:CountDownLatch(倒计数门闩)、CyclicBarrier(循环障栅)、Semaphore(信号量)等。你这里适合使用前两种,最适合使用第二个 CyclicBarrierCyclicBarrier大高手能写个例子吗?看看高手都是怎么写代码的啊。
      

  4.   

    package houlei.csdn.mutiThreads;import java.io.Serializable;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;public class ThreadPoolTaskF { public static void main(String[] args) throws InterruptedException {
    final int PoolSize = 2;//线程池的线程数。
    final int QueueSize = 2;//阻塞队列的线程数。
    final int BatchSize = 5;//每批次执行的任务数。
    //一共有几个线程来执行任务。(策略决定主线程参与任务执行,所以,1代表主线程)
    final int TaskExecutors = PoolSize+1;
            LogUtil.log("Total Start...................");
            ThreadPoolExecutor threadPool = new ThreadPoolExecutor(PoolSize, PoolSize, 1,
                    TimeUnit.HOURS, new ArrayBlockingQueue<Runnable>(QueueSize),
                    new ThreadPoolExecutor.CallerRunsPolicy());
            CyclicBarrier barrier = new CyclicBarrier(TaskExecutors);
            for (int i = 0; i < 2; i++) {
             LogUtil.log("For :: i=" + i );
                for (int j = 0; j < BatchSize; j++) {
                    threadPool.execute(new ThreadPoolTask(" i=" + i + " j=" + j,j<BatchSize-TaskExecutors?null:barrier ));
                }
                LogUtil.log("End For");
            }
            threadPool.shutdown();
            LogUtil.log("Total End...................");
        }
        public static void getV(String str) throws InterruptedException {
            Thread.sleep(1000 * 10);// 10秒
            LogUtil.log("getV :: " + str);
        }
        public static class ThreadPoolTask implements Runnable, Serializable {
            private static final long serialVersionUID = 0;
            private CyclicBarrier barrier;
            private Object threadPoolTaskData1;
            ThreadPoolTask(Object tasks1, CyclicBarrier barrier) {
                this.threadPoolTaskData1 = tasks1;
                this.barrier=barrier;
            }
            public void run() {
                try {
                    getV(threadPoolTaskData1.toString());
                    if(null!=barrier){
                     //LogUtil.log("Barrier Await");
                     barrier.await();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class LogUtil{
    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
    public static void log(String msg){
    System.out.println(sdf.format(new Date())+" ["+Thread.currentThread().getName()+"]\t"+msg);
    }
    }
      

  5.   

    CyclicBarrier 楼上已经给你举例了。说实在的你很懒呢,CyclicBarrier 在 API 文档上已经说得很详细了,而且 API 文档上也是有例子的!拒绝策略 ThreadPoolExecutor.CallerRunsPolicy 就是这样的,你去看一下这个类的源代码就知道了。从名字上也可以看出 CallerRuns —— 调用者运行,也就是时需要使用拒绝策略时,哪个线程调用了 Executor 的 execute 方法,就由该调用线程来执行这个任务。说白了就是直接调用 run 方法执行。
      

  6.   

    你设定的拒绝策略是 ThreadPoolExecutor.CallerRunsPolicy。因此,任务不会采用异步方式执行,而是直接调用了 run 方法采取同步执行的方式。红色部分的意思是不是说。如果线程池的线程在忙新的任务就交给主线程了啊?能正面回答我这个问题吗?是或者不是啊?