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

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

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

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

时间: 2024-11-06 11:04:10

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

从Uber和快的、滴滴、易到App对比看人性

如果你认识一个朋友经常对你说谎话,或者给你很多不确定性,或者会让你感觉到不信任感,或者稍微不慎就可能被他骗,或者一不小心就会掉到他设计的''坑''里,我想任何人都是不愿意交这样的朋友的,大家愿意交真诚,善良,靠谱的,没有那么多花花肠子的人,这个是人的共性. 对于一些打车App也一样,在移动互联网App流行的今天,碎片化时间使得我们大部分人每天都要花2个多小时以上的时间在App上(数据来自网络),在这些时间里,我们和这些App交互,点击启动,输入文字,说话,享受优惠,预测自己的行程等等,App就像

(转) Ringbuffer为什么这么快?

原文地址:http://ifeve.com/ringbuffer/ 最近,我们开源了LMAX Disruptor,它是我们的交易系统吞吐量快(LMAX是一个新型的交易平台,号称能够单线程每秒处理数百万的订单)的关键原因.为什么我们要将其开源?我们意识到对高性能编程领域的一些传统观点,有点不对劲.我们找到了一种更好.更快地在线程间共享数据的方法,如果不公开于业界共享的话,那未免太自私了.同时开源也让我们觉得看起来更酷. 从这个站点,你可以下载到一篇解释什么是Disruptor及它为什么如此高性能的

从零开始学多线程之构建快(四)

前文回顾 上一篇博客 从零开始学多线程之组合对象(三) 主要讲解了: 1. 设计线程安全的类要考虑的因素. 2. 对于非线程安全的对象,我们可以考虑使用锁+实例限制(Java监视器模式)的方式,安全的访问它们. 3. 扩展线程安全类的四种方式. 本篇博客将要讲解的知识点 使用java提供的线程安全容器和同步工具.来构建线程安全的类. 这些同步工具包括: 同步容器.并发容器和阻塞队列. 开始之前先介绍几个简单的基础知识: Thread.Runnable 和 Callable.  Runnable是

NODE.js同步调用获取mysql快3网站搭建数据时遇到的大坑

mysql调用获取数据,快3网站搭建[企鹅21717-93408]只能是异步方式返回结果,不能同步获取结果,因此,须在回调函数中编写处理事件.期间看了下Aysnc.js,是用于多个要返回回调函数的事件,将这些事件有序的组织起来,最后只返回一个回调函数,并没有改变异步的本质,而是将多个异步整合为一个异步,从而满足写程序的需求. 错误示范 获取数据库中的数据函数 var _getUser = function(name) {var sql = "SELECT * FROM " + TABL

5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践

5.5 进入编辑模式 5.6 vim命令模式 5.7 vim实践 扩展 vim的特殊用法 http://www.apelearn.com/bbs/thread-9334-1-1.html vim常用快捷键总结 http://www.apelearn.com/bbs/thread-407-1-1.html vim快速删除一段字符 http://www.apelearn.com/bbs/thread-842-1-1.html vim乱码 http://www.apelearn.com/bbs/thr

电商邮件服务平台性能优化谈

从今年一月份开始,团队陆续完成了邮件服务的架构升级.新平台上线运行的过程中也发生了一系列的性能问题,即使很多看起来微不足道的点也会让整个系统运行得不是那么平稳,今天就将这段时间的问题以及解决方案统一整理下,希望能起到抛砖的作用,让读者在遇到类似问题的时候能多一个解决方案. 新平台上线后第一版架构如下: 这版架构上线后,我们遇到的第一个问题:数据库读写压力过大后影响整体服务稳定. 表现为: 1.数据库主库压力高,同时伴有大量的读,写操作. 2.远程服务接口性能不稳定,业务繁忙时数据库的插入操作延迟

redis单线程问题

1.redis的单线程指的是什么单线程?同一个时间点只处理一个客户端的连接,也就是redis网络模块的单线程. 2.redis为什么设计成单线程 具体作者怎么想的,我不知道,我说一下我的理解(1)redis用的是非阻塞IO,非阻塞I/O本身就可以是单线程处理多个请求(2)如果用多线程,就要考虑线程的上下文切换,和锁的请求和释放,这些操作也比较耗时,锁等待更容易把业务线程池占满(3)在我看来,Redis的设计理念就是短平快,在保证完全内存计算的情况下,能串行的地方就串行,在处理socket请求这块

Linux CentOS7 中vim命令的使用

一. vim介绍 vim 是vi 的升级版本:可带颜色显示 1. 安装vim yum install -y vim-enhancedvim /etc/passwd 2. 三种模式: 一般模式:dd p yy  编辑模式:编辑文件内容 命令模式::/ ? 二. vim颜色显示和移动光标 1. vim 可以根据文件的路径和名字显示颜色 cp /etc/passwd /tmp  vim /tmp/passwd 查看就无颜色 /etc 下会显示颜色,是他的特性.cp /etc/fstab /tmpvim

R语言基因组数据分析可能会用到的data.table函数整理

R语言data.table包是自带包data.frame的升级版,用于数据框格式数据的处理,最大的特点快.包括两个方面,一方面是写的快,代码简洁,只要一行命令就可以完成诸多任务,另一方面是处理快,内部处理的步骤进行了程序上的优化,使用多线程,甚至很多函数是使用C写的,大大加快数据运行速度.因此,在对大数据处理上,使用data.table无疑具有极高的效率.这里主要介绍在基因组数据分析中可能会用到的函数. fread 做基因组数据分析时,常常需要读入处理大文件,这个时候我们就可以舍弃read.ta