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


               做多任务开发经常有这种需求。在主线程开多个子线程。可是主线程往往须要这些子线程的运算结果才干进行接下来的运算。怎么办呢,小弟封装了一个触发器,能够满足上述要求,代码非常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);

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

  • 相关阅读:
    java request.getInputStream中文乱码解决方案
    MySql5.7配置文件my.ini 设置 my.ini文件路径
    PostgreSQL抛错“不良的类型值: long”之解决
    PostgreSQL-JDBC疑似bug:部分接口参数的表名、列名必须全部小写
    PostgreSQL的空串、空值对唯一性约束的影响
    JPA/Hibernate移植到PostgreSQL时关于CLOB, BLOB及JSON类型的处理
    PostgreSQL函数自动Commit/Rollback所带来的问题
    JBoss EAP 为应用项目配置PostgreSQL数据源
    PostgreSQL 9.4使用UUID
    PostgreSQL视图使用特殊名称作字段时的处理
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6979695.html
Copyright © 2020-2023  润新知