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

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

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

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);

的凝视。程序马上锁死,这是在使用中应该高度注意的一点。眼下还没找到从语法层面避免这样的错误的方法。要是有可以在语法检查阶段提醒程序猿的办法那就完美了。

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