快的等哈慢的,要有团体意识——异步多任务等待之触发器模式


           做多任务开发常常有这样的需求,在主线程开多个子线程,但是主线程往往需要这些子线程的运算结果才能进行接下来的运算,怎么办呢,小弟封装了一个触发器,可以满足上述要求,代码很简单,功能很强大,先上代码:

package com.zjg.smart.async;

 

import java.text.SimpleDateFormat;

import java.util.Arrays;

import java.util.Date;

 

import com.zjg.smart.utils.DebugUtils;

 

public class Trigger {

 

    /**

     * 当有触发器被触发时进行监听

     *

     * @author周继光

     *

     */

    public interface OnTriggerListener {

       /**

        *

        * @param currentIndex

        *            当前触发器索引

        * @param count

        *            触发器总数

        * @param remainder

        *            没有触发的触发器数量

        * @param triggers

        *            触发器

        * @param enables

        *            控制触发器是否有效的开关

        */

       public void onTriiger(int currentIndex,int count,int remainder,

              boolean[] triggers,boolean[] enables);

    }

 

    private boolean[] triggers;

    private boolean[] enables;

    private int currentIndex;

    private boolean waiting;

 

    /**

     *

     * @param count

     *            指定触发器总数

     */

    public Trigger(int count) {

       super();

       if (count <= 0) {

           throw new IllegalArgumentException(DebugUtils.STACK_TRACE()

                  + "count mustbe greater than 0");

       }

       triggers = newboolean[count];

       enables = newboolean[count];

    }

 

    /**

     * 复位所有触发器

     */

    public synchronized void rest() {

       Arrays.fill(triggers,false);

    }

 

    /**

     * 等待所有触发器

     */

    public void waitAll() {

       waitAll(null);

    }

 

    public synchronized void waitAll(OnTriggerListener onTriggerListener) {

       Arrays.fill(enables,true);

       while (true) {

           waiting = true;

           notifyAll();

           try {

              wait();

           } catch (InterruptedException e) {

              // TODO自动生成的 catch

              e.printStackTrace();

           }

           boolean leave =true;

           int remainder = 0;

           for (int i = 0, length =triggers.length; i < length; i++) {

              if (enables[i] && !triggers[i]) {

                  leave = false;

                  remainder++;

              }

           }

           if (enables[currentIndex] && onTriggerListener !=null) {

              onTriggerListener.onTriiger(currentIndex,triggers.length,

                     remainder, Arrays.copyOf(triggers,triggers.length),

                     Arrays.copyOf(enables,enables.length));

           }

           if (leave) {

              waiting = false;

              break;

           }

       }

    }

 

    /**

     * 有选择地等待某个触发器

     *

     * @param indices

     *            指定等待的触发器

     */

    public synchronized void waitSome(int... indices) {

       waitSome(null, indices);

    }

 

    public synchronized void waitSome(OnTriggerListener onTriggerListener,

           int... indices) {

       Arrays.fill(enables,false);

       for (int i = 0, length = indices.length; i < length; i++) {

           if (indices[i] >=enables.length) {

              throw new IndexOutOfBoundsException(DebugUtils.STACK_TRACE()

                     + "index =" + indices[i] +", count = "

                     + enables.length);

           }

           enables[indices[i]] =true;

       }

       while (true) {

           waiting = true;

           notifyAll();

           try {

              wait();

           } catch (InterruptedException e) {

              // TODO自动生成的 catch

              e.printStackTrace();

           }

           boolean leave =true;

           int remainder = 0;

           for (int i = 0, length =triggers.length; i < length; i++) {

              if (enables[i] && !triggers[i]) {

                  leave = false;

                  remainder++;

              }

           }

           if (enables[currentIndex] && onTriggerListener !=null) {

              onTriggerListener.onTriiger(currentIndex, indices.length,

                     remainder, Arrays.copyOf(triggers,triggers.length),

                     Arrays.copyOf(enables,enables.length));

           }

           if (leave) {

              waiting = false;

              break;

           }

       }

    }

 

    /**

     * 触发

     *

     * @param index

     *            被触发的触发器索引,从0开始

     */

    public synchronized void trigger(int index) {

       if (!waiting) {

           try {

              wait();

           } catch (InterruptedException e) {

              // TODO自动生成的 catch

              e.printStackTrace();

           }

       }

       if (index >=triggers.length) {

           throw new IndexOutOfBoundsException(DebugUtils.STACK_TRACE()

                  + "index =" + index +", count = " +triggers.length);

       }

       if (enables[index]) {

           triggers[index] = true;

       }

       currentIndex = index;

       notifyAll();

    }

 






下面是测试代码:

    private static void test1() {

       System.out.println("test1() 测试说明:12个线程,只等待序号为13的线程结束后,主线程便结束。");

       final SimpleDateFormat simpleDateFormat =new SimpleDateFormat(

              "yyyy-MM-ddhh:mm:ss:ssss");

       int count = 12;

       long tStart = System.currentTimeMillis();

       System.out.println(Thread.currentThread().getName() +"开始于"

              + simpleDateFormat.format(new Date()));//打印开始标记

       final Trigger trigger =new Trigger(count);

       for (int ii = 0; ii < count; ii++) {//threadNum个线程

           final int index = ii;

           Runnable r = new Runnable() {

              @Override

              public void run() {

                  // TODO自动生成的方法存根

                  long start = System.currentTimeMillis();

                  System.out.println(Thread.currentThread().getName() +"开始"

                         + simpleDateFormat.format(new Date()));

                  // 做一些事情... ...

                  try {

                     Thread.sleep(index * 50);

                  } catch (InterruptedException e) {

                     // TODO自动生成的 catch

                     e.printStackTrace();

                  }

                  System.out

                         .println(Thread.currentThread().getName()+"结束于"

                                + simpleDateFormat.format(new Date())

                                + ",用时"

                                + (System.currentTimeMillis()- start)

                                + "millions");

                  trigger.trigger(index);

              }

           };

           Thread t = new Thread(r);

           t.start();

       }

       trigger.waitSome(new OnTriggerListener() {

 

           @Override

           public void onTriiger(int currentIndex,int count,int remainder,

                  boolean[] triggers,boolean[] enables) {

              // TODO自动生成的方法存根

              StringBuffer triggerIndicesMsg = new StringBuffer();

              int k = 0;

              for (int i = 0, length = triggers.length; i < length; i++) {

                  if (enables[i] && !triggers[i]) {

                     if (k > 0) {

                         triggerIndicesMsg.append("");

                     }

                     triggerIndicesMsg.append(i);

                     k++;

                  }

              }

              System.out.println("" + currentIndex +"个触发器触发,总触发器:" + count

                     + ",还有" + remainder +"个触发器没有触发,分别是"

                     + triggerIndicesMsg.toString() + ",触发器状态"

                     + Arrays.toString(triggers));

           }

       }, 1, 3);

       System.out.println(Thread.currentThread().getName() +"结束于"

              + simpleDateFormat.format(new Date()));//打印结束标记

       long tEnd = System.currentTimeMillis();

       System.out.println("总共用时:" + (tEnd - tStart) +"millions");

    }

 

    private static void test2() {

       System.out.println("test2() 测试说明:12个线程,等待全部线程结束后,主线程才结束。");

       final SimpleDateFormat simpleDateFormat =new SimpleDateFormat(

              "yyyy-MM-ddhh:mm:ss:ssss");

       int count = 12;

       long tStart = System.currentTimeMillis();

       System.out.println(Thread.currentThread().getName() +"开始于"

              + simpleDateFormat.format(new Date()));//打印开始标记

       final Trigger trigger =new Trigger(count);

       for (int ii = 0; ii < count; ii++) {//threadNum个线程

           final int index = ii;

           Runnable r = new Runnable() {

              @Override

              public void run() {

                  // TODO自动生成的方法存根

                  long start = System.currentTimeMillis();

                  System.out.println(Thread.currentThread().getName() +"开始"

                         + simpleDateFormat.format(new Date()));

                  // 做一些事情... ...

                  try {

                     Thread.sleep(index * 50);

                  } catch (InterruptedException e) {

                     // TODO自动生成的 catch

                     e.printStackTrace();

                  }

                  System.out

                         .println(Thread.currentThread().getName()+"结束于"

                                + simpleDateFormat.format(new Date())

                                + ",用时"

                                + (System.currentTimeMillis()- start)

                                + "millions");

                  trigger.trigger(index);

              }

           };

           Thread t = new Thread(r);

           t.start();

       }

       trigger.waitAll(new OnTriggerListener() {

 

           @Override

           public void onTriiger(int currentIndex,int count,int remainder,

                  boolean[] triggers,boolean[] enables) {

              // TODO自动生成的方法存根

              StringBuffer triggerIndicesMsg = new StringBuffer();

              int k = 0;

              for (int i = 0, length = triggers.length; i < length; i++) {

                  if (enables[i] && !triggers[i]) {

                     if (k > 0) {

                         triggerIndicesMsg.append("");

                     }

                     triggerIndicesMsg.append(i);

                     k++;

                  }

              }

              System.out.println("" + currentIndex +"个触发器触发,总触发器:" + count

                     + ",还有" + remainder +"个触发器没有触发,分别是"

                     + triggerIndicesMsg.toString() + ",触发器状态"

                     + Arrays.toString(triggers));

           }

       });

       System.out.println(Thread.currentThread().getName() +"结束于"

              + simpleDateFormat.format(new Date()));//打印结束标记

       long tEnd = System.currentTimeMillis();

       System.out.println("总共用时:" + (tEnd - tStart) +"millions");

    }

 

    private static void test3() {

       System.out.println("test3() 测试说明:12个线程,主线程谁都不等就结束。");

       final SimpleDateFormat simpleDateFormat =new SimpleDateFormat(

              "yyyy-MM-ddhh:mm:ss:ssss");

       int count = 12;

       long tStart = System.currentTimeMillis();

       System.out.println(Thread.currentThread().getName() +"开始于"

              + simpleDateFormat.format(new Date()));//打印开始标记

       final Trigger trigger =new Trigger(count);

       for (int ii = 0; ii < count; ii++) {//threadNum个线程

           final int index = ii;

           Runnable r = new Runnable() {

              @Override

              public void run() {

                  // TODO自动生成的方法存根

                  long start = System.currentTimeMillis();

                  System.out.println(Thread.currentThread().getName() +"开始"

                         + simpleDateFormat.format(new Date()));

                  // 做一些事情... ...

                  try {

                     Thread.sleep(index * 50);

                  } catch (InterruptedException e) {

                     // TODO自动生成的 catch

                     e.printStackTrace();

                  }

                  System.out

                         .println(Thread.currentThread().getName()+"结束于"

                                + simpleDateFormat.format(new Date())

                                + ",用时"

                                + (System.currentTimeMillis()- start)

                                + "millions");

                  trigger.trigger(index);

              }

           };

           Thread t = new Thread(r);

           t.start();

       }

       trigger.waitSome(new OnTriggerListener() {

 

           @Override

           public void onTriiger(int currentIndex,int count,int remainder,

                  boolean[] triggers,boolean[] enables) {

              // TODO自动生成的方法存根

              StringBuffer triggerIndicesMsg = new StringBuffer();

              int k = 0;

              for (int i = 0, length = triggers.length; i < length; i++) {

                  if (enables[i] && !triggers[i]) {

                     if (k > 0) {

                         triggerIndicesMsg.append("");

                     }

                     triggerIndicesMsg.append(i);

                     k++;

                  }

              }

              System.out.println("" + currentIndex +"个触发器触发,总触发器:" + count

                     + ",还有" + remainder +"个触发器没有触发,分别是"

                     + triggerIndicesMsg.toString() + ",触发器状态"

                     + Arrays.toString(triggers));

           }

       });

       System.out.println(Thread.currentThread().getName() +"结束于"

              + simpleDateFormat.format(new Date()));//打印结束标记

       long tEnd = System.currentTimeMillis();

       System.out.println("总共用时:" + (tEnd - tStart) +"millions");

    }

 

    public static void main(String[] args) {

 

    }

}






主要思路就是循环判断触发器是否都触发了,是则跳出循环,否则继续等待。代码也比较简单,注释也详细,应该不难看懂,效果却不错,在此也贴上测试结果吧:


test1()测试说明: 开12个线程,只等待序号为1、3的线程结束后,主线程便结束。
main开始于2015-08-10 04:55:11:0011
Thread-1开始2015-08-10 04:55:11:0011
Thread-2开始2015-08-10 04:55:11:0011
Thread-0开始2015-08-10 04:55:11:0011
Thread-3开始2015-08-10 04:55:11:0011
Thread-4开始2015-08-10 04:55:11:0011
Thread-5开始2015-08-10 04:55:11:0011
Thread-0结束于2015-08-10 04:55:11:0011,用时0millions
Thread-6开始2015-08-10 04:55:11:0011
Thread-7开始2015-08-10 04:55:11:0011
Thread-8开始2015-08-10 04:55:11:0011
Thread-9开始2015-08-10 04:55:11:0011
Thread-10开始2015-08-10 04:55:11:0011
Thread-11开始2015-08-10 04:55:11:0011
Thread-1结束于2015-08-10 04:55:11:0011,用时47millions
第1个触发器触发,总触发器:2,还有1个触发器没有触发,分别是3,触发器状态[false, true, false, false, false, false, false, false, false, false, false, false]
Thread-2结束于2015-08-10 04:55:11:0011,用时94millions
Thread-3结束于2015-08-10 04:55:11:0011,用时141millions
第3个触发器触发,总触发器:2,还有0个触发器没有触发,分别是,触发器状态[false, true, false, true, false, false, false, false, false, false, false, false]
main结束于2015-08-10 04:55:11:0011
总共用时:141millions
Thread-4结束于2015-08-10 04:55:11:0011,用时188millions
Thread-5结束于2015-08-10 04:55:11:0011,用时250millions
Thread-6结束于2015-08-10 04:55:11:0011,用时297millions
Thread-7结束于2015-08-10 04:55:11:0011,用时344millions
Thread-8结束于2015-08-10 04:55:11:0011,用时391millions
Thread-9结束于2015-08-10 04:55:11:0011,用时438millions
Thread-10结束于2015-08-10 04:55:11:0011,用时500millions
Thread-11结束于2015-08-10 04:55:11:0011,用时547millions

 可以看到当第1、3触发器触发后,main线程就结束,而其它线程还在继续。


test2()测试说明: 开12个线程,等待全部线程结束后,主线程才结束。
main开始于2015-08-10 05:00:57:0057
Thread-0开始2015-08-10 05:00:57:0057
Thread-1开始2015-08-10 05:00:57:0057
Thread-0结束于2015-08-10 05:00:57:0057,用时0millions
Thread-2开始2015-08-10 05:00:57:0057
Thread-3开始2015-08-10 05:00:57:0057
Thread-4开始2015-08-10 05:00:57:0057
Thread-5开始2015-08-10 05:00:57:0057
Thread-6开始2015-08-10 05:00:57:0057
Thread-7开始2015-08-10 05:00:57:0057
Thread-8开始2015-08-10 05:00:57:0057
Thread-9开始2015-08-10 05:00:57:0057
Thread-10开始2015-08-10 05:00:57:0057
Thread-11开始2015-08-10 05:00:57:0057
第0个触发器触发,总触发器:12,还有11个触发器没有触发,分别是1、2、3、4、5、6、7、8、9、10、11,触发器状态[true, false, false, false, false, false, false, false, false, false, false, false]
Thread-1结束于2015-08-10 05:00:57:0057,用时47millions
第1个触发器触发,总触发器:12,还有10个触发器没有触发,分别是2、3、4、5、6、7、8、9、10、11,触发器状态[true, true, false, false, false, false, false, false, false, false, false, false]
Thread-2结束于2015-08-10 05:00:57:0057,用时110millions
第2个触发器触发,总触发器:12,还有9个触发器没有触发,分别是3、4、5、6、7、8、9、10、11,触发器状态[true, true, true, false, false, false, false, false, false, false, false, false]
Thread-3结束于2015-08-10 05:00:57:0057,用时157millions
第3个触发器触发,总触发器:12,还有8个触发器没有触发,分别是4、5、6、7、8、9、10、11,触发器状态[true, true, true, true, false, false, false, false, false, false, false, false]
Thread-4结束于2015-08-10 05:00:57:0057,用时204millions
第4个触发器触发,总触发器:12,还有7个触发器没有触发,分别是5、6、7、8、9、10、11,触发器状态[true, true, true, true, true, false, false, false, false, false, false, false]
Thread-5结束于2015-08-10 05:00:57:0057,用时250millions
第5个触发器触发,总触发器:12,还有6个触发器没有触发,分别是6、7、8、9、10、11,触发器状态[true, true, true, true, true, true, false, false, false, false, false, false]
Thread-6结束于2015-08-10 05:00:57:0057,用时297millions
第6个触发器触发,总触发器:12,还有5个触发器没有触发,分别是7、8、9、10、11,触发器状态[true, true, true, true, true, true, true, false, false, false, false, false]
Thread-7结束于2015-08-10 05:00:57:0057,用时360millions
第7个触发器触发,总触发器:12,还有4个触发器没有触发,分别是8、9、10、11,触发器状态[true, true, true, true, true, true, true, true, false, false, false, false]
Thread-8结束于2015-08-10 05:00:57:0057,用时407millions
第8个触发器触发,总触发器:12,还有3个触发器没有触发,分别是9、10、11,触发器状态[true, true, true, true, true, true, true, true, true, false, false, false]
Thread-9结束于2015-08-10 05:00:57:0057,用时454millions
第9个触发器触发,总触发器:12,还有2个触发器没有触发,分别是10、11,触发器状态[true, true, true, true, true, true, true, true, true, true, false, false]
Thread-10结束于2015-08-10 05:00:57:0057,用时500millions
第10个触发器触发,总触发器:12,还有1个触发器没有触发,分别是11,触发器状态[true, true, true, true, true, true, true, true, true, true, true, false]
Thread-11结束于2015-08-10 05:00:57:0057,用时547millions
第11个触发器触发,总触发器:12,还有0个触发器没有触发,分别是,触发器状态[true, true, true, true, true, true, true, true, true, true, true, true]
main结束于2015-08-10 05:00:57:0057
总共用时:547millions

可以看到全部线程结束后,main线程才结束,并且main线程耗时与耗时最多的线程是一样的,由此可见多任务的性能是多么高效的。


test3()测试说明: 开12个线程,主线程谁都不等就结束。
main开始于2015-08-10 05:03:54:0054
Thread-0开始2015-08-10 05:03:54:0054
Thread-1开始2015-08-10 05:03:54:0054
Thread-0结束于2015-08-10 05:03:54:0054,用时0millions
Thread-2开始2015-08-10 05:03:54:0054
Thread-4开始2015-08-10 05:03:54:0054
Thread-3开始2015-08-10 05:03:54:0054
Thread-5开始2015-08-10 05:03:54:0054
Thread-8开始2015-08-10 05:03:54:0054
Thread-7开始2015-08-10 05:03:54:0054
Thread-9开始2015-08-10 05:03:54:0054
Thread-6开始2015-08-10 05:03:54:0054
Thread-11开始2015-08-10 05:03:54:0054
Thread-10开始2015-08-10 05:03:54:0054
main结束于2015-08-10 05:03:54:0054
总共用时:16millions
Thread-1结束于2015-08-10 05:03:54:0054,用时46millions
Thread-2结束于2015-08-10 05:03:54:0054,用时93millions
Thread-3结束于2015-08-10 05:03:54:0054,用时140millions
Thread-4结束于2015-08-10 05:03:54:0054,用时187millions
Thread-5结束于2015-08-10 05:03:54:0054,用时250millions
Thread-6结束于2015-08-10 05:03:54:0054,用时296millions
Thread-7结束于2015-08-10 05:03:54:0054,用时343millions
Thread-8结束于2015-08-10 05:03:54:0054,用时390millions
Thread-9结束于2015-08-10 05:03:54:0054,用时437millions
Thread-10结束于2015-08-10 05:03:54:0054,用时500millions
Thread-11结束于2015-08-10 05:03:54:0054,用时546millions

可以看到main是开完所有线程就结束了,没有进行等待。


注:trigger(int index)函数中:

  public synchronized void trigger(int index) {

               if (!waiting) {
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}

                ...

    }

    wait...函数中:

    while (true) {

        ...

        waiting = true;
        notifyAll();

        ...

        if (leave) {
   waiting = false;

           ...

    }

    这些代码用于防止触发器还没有入等待状态就触发了,如果没有这些代码,那么当线程执行得很快,比如例程中的线程0,main线程还没有进入等待状态,它就已经把触发器给触发了,造成main线程永远也等不来它的触发,main线程就会锁死。

    有这些代码在,当子线程触发触发器时,如果主线程还没有进入等待状态,那么子线程也会等待,直到主线程进入等待状态它才会触发。



补充一个烧脑例程吧,同时说明一个重大使用问题:

private static void test4() {

       System.out

              .println("test4()测试说明:开一个管理线程后主线程立即结束,在管理线程中开12个工作线程,在管理线程中等待全部工作线程结束后才结束。");

       final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(

              "yyyy-MM-ddhh:mm:ss:ssss");

       final int count = 12;

       long mainStart = System.currentTimeMillis();

       System.out.println(Thread.currentThread().getName() + "开始于"

              + simpleDateFormat.format(new Date()));// 打印开始标记

       final Trigger trigger = new Trigger(count);

       new Thread() {

 

           @Override

           public void run() {

              // TODO自动生成的方法存根

              super.run();

              long managerStart = System.currentTimeMillis();

              System.out.println(Thread.currentThread().getName() + "开始于"

                     + simpleDateFormat.format(new Date()));// 打印开始标记

 

              // 在等待的线程触发,程序将进入死锁状态

              //trigger.trigger(0);

 

              for (int ii = 0; ii < count; ii++) {// threadNum个线程

                  final int index = ii;

                  new Thread() {

                     @Override

                     public void run() {

                         // TODO自动生成的方法存根

                         long start = System.currentTimeMillis();

                         System.out.println(Thread.currentThread().getName()

                                + "开始"

                                + simpleDateFormat.format(new Date()));

                         // 做一些事情... ...

                         try {

                            Thread.sleep(index * 50);

                         } catch (InterruptedException e) {

                            // TODO自动生成的 catch

                            e.printStackTrace();

                         }

                         System.out.println(Thread.currentThread().getName()

                                + "结束于"

                                + simpleDateFormat.format(new Date())

                                + ",用时"

                                + (System.currentTimeMillis()- start)

                                + "millions");

                         trigger.trigger(index);

                     }

                  }.start();

              }

              trigger.waitAll(new OnTriggerListener() {

 

                  @Override

                  public void onTriiger(int currentIndex, int count,

                         int remainder, boolean[] triggers, boolean[] enables) {

                     // TODO自动生成的方法存根

                     StringBuffer triggerIndicesMsg = new StringBuffer();

                     int k = 0;

                     for (int i = 0, length = triggers.length; i < length; i++) {

                         if (enables[i] && !triggers[i]) {

                            if (k > 0) {

                                triggerIndicesMsg.append("");

                            }

                            triggerIndicesMsg.append(i);

                            k++;

                         }

                     }

                     System.out.println("" + currentIndex + "个触发器触发,总触发器:"

                            + count + ",还有" + remainder + "个触发器没有触发,分别是"

                            + triggerIndicesMsg.toString() + ",触发器状态"

                            + Arrays.toString(triggers));

                  }

              });

              System.out.println(Thread.currentThread().getName() + "结束于"

                     + simpleDateFormat.format(new Date()) + ",用时"

                     + (System.currentTimeMillis() -managerStart)

                     + "millions");// 打印结束标记

           }

 

       }.start();

       System.out.println(Thread.currentThread().getName() + "结束于"

              + simpleDateFormat.format(new Date()) + ",用时"

              + (System.currentTimeMillis() - mainStart) + "millions");// 打印结束标记

    }



下面是运行结果:

test4()测试说明: 开一个管理线程后主线程立即结束,在管理线程中开12个工作线程,在管理线程中等待全部工作线程结束后才结束。

main开始于2015-08-1109:40:30:0030

main结束于2015-08-1109:40:30:0030,用时0millions

Thread-0开始于2015-08-1109:40:30:0030

Thread-1开始2015-08-1109:40:30:0030

Thread-2开始2015-08-1109:40:30:0030

Thread-1结束于2015-08-1109:40:30:0030,用时0millions

Thread-3开始2015-08-1109:40:30:0030

Thread-4开始2015-08-1109:40:30:0030

Thread-5开始2015-08-1109:40:30:0030

Thread-6开始2015-08-1109:40:30:0030

Thread-7开始2015-08-1109:40:30:0030

Thread-8开始2015-08-1109:40:30:0030

Thread-9开始2015-08-1109:40:30:0030

Thread-10开始2015-08-1109:40:30:0030

Thread-11开始2015-08-1109:40:30:0030

Thread-12开始2015-08-1109:40:30:0030

第0个触发器触发,总触发器:12,还有11个触发器没有触发,分别是1、2、3、4、5、6、7、8、9、10、11,触发器状态[true, false, false, false, false, false, false, false,false, false, false, false]

Thread-2结束于2015-08-1109:40:30:0030,用时62millions

第1个触发器触发,总触发器:12,还有10个触发器没有触发,分别是2、3、4、5、6、7、8、9、10、11,触发器状态[true, true, false, false, false, false, false, false,false, false, false, false]

Thread-3结束于2015-08-1109:40:30:0030,用时109millions

第2个触发器触发,总触发器:12,还有9个触发器没有触发,分别是3、4、5、6、7、8、9、10、11,触发器状态[true, true, true, false, false, false, false, false,false, false, false, false]

Thread-4结束于2015-08-1109:40:30:0030,用时156millions

第3个触发器触发,总触发器:12,还有8个触发器没有触发,分别是4、5、6、7、8、9、10、11,触发器状态[true, true, true, true, false, false, false, false,false, false, false, false]

Thread-5结束于2015-08-1109:40:31:0031,用时203millions

第4个触发器触发,总触发器:12,还有7个触发器没有触发,分别是5、6、7、8、9、10、11,触发器状态[true, true, true, true, true, false, false, false,false, false, false, false]

Thread-6结束于2015-08-1109:40:31:0031,用时250millions

第5个触发器触发,总触发器:12,还有6个触发器没有触发,分别是6、7、8、9、10、11,触发器状态[true, true, true, true, true, true, false, false, false,false, false, false]

Thread-7结束于2015-08-1109:40:31:0031,用时312millions

第6个触发器触发,总触发器:12,还有5个触发器没有触发,分别是7、8、9、10、11,触发器状态[true, true, true, true, true, true, true, false, false,false, false, false]

Thread-8结束于2015-08-1109:40:31:0031,用时359millions

第7个触发器触发,总触发器:12,还有4个触发器没有触发,分别是8、9、10、11,触发器状态[true, true, true, true, true, true, true, true, false,false, false, false]

Thread-9结束于2015-08-1109:40:31:0031,用时406millions

第8个触发器触发,总触发器:12,还有3个触发器没有触发,分别是9、10、11,触发器状态[true, true, true, true, true, true, true, true, true,false, false, false]

Thread-10结束于2015-08-1109:40:31:0031,用时453millions

第9个触发器触发,总触发器:12,还有2个触发器没有触发,分别是10、11,触发器状态[true, true, true, true, true, true, true, true, true,true, false, false]

Thread-11结束于2015-08-1109:40:31:0031,用时500millions

第10个触发器触发,总触发器:12,还有1个触发器没有触发,分别是11,触发器状态[true, true, true, true, true, true, true, true, true,true, true, false]

Thread-12结束于2015-08-1109:40:31:0031,用时562millions

第11个触发器触发,总触发器:12,还有0个触发器没有触发,分别是,触发器状态[true, true, true, true, true, true, true, true, true,true, true, true]

Thread-0结束于2015-08-11 09:40:31:0031,用时562millions


重点说明:wait...()和triiger()不能在同一个线程里,不信去掉test4()

// 在等待的线程触发,程序将进入死锁状态

 //trigger.trigger(0);

的注释,程序立即锁死,这是在使用中应该高度注意的一点,目前还没找到从语法层面避免这种错误的方法,要是有能够在语法检查阶段提醒程序员的办法那就完美了。

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告