线程通信

Auto.js 提供了一些简单的设施来支持简单的线程通信。threads.disposable()用于一个线程等待另一个线程的(一次性)结果,同时Lock.newCondition()提供了 Condition 对象用于一般的线程通信(await, signal)。另外,events模块也可以用于线程通信,通过指定EventEmiiter的回调执行的线程来实现。

使用threads.disposable()可以简单地等待和获取某个线程的执行结果。例如要等待某个线程计算"1+.....+10000":

1var sum = threads.disposable();
2//启动子线程计算
3threads.start(function () {
4    var s = 0;
5    //从1加到10000
6    for (var i = 1; i <= 10000; i++) {
7        s += i;
8    }
9    //通知主线程接收结果
10    sum.setAndNotify(s);
11});
12//blockedGet()用于等待结果
13toast("sum = " + sum.blockedGet());

如果上述代码用Condition实现:

1//新建一个锁
2var lock = threads.lock();
3//新建一个条件,即"计算完成"
4var complete = lock.newCondition();
5var sum = 0;
6threads.start(function () {
7    //从1加到10000
8    for (var i = 1; i <= 10000; i++) {
9        sum += i;
10    }
11    //通知主线程接收结果
12    lock.lock();
13    complete.signal();
14    lock.unlock();
15});
16//等待计算完成
17lock.lock();
18complete.await();
19lock.unlock();
20//打印结果
21toast("sum = " + sum);

如果上诉代码用events模块实现:

1//新建一个emitter, 并指定回调执行的线程为当前线程
2var sum = events.emitter(threads.currentThread());
3threads.start(function () {
4    var s = 0;
5    //从1加到10000
6    for (var i = 1; i <= 10000; i++) {
7        s += i;
8    }
9    //发送事件result通知主线程接收结果
10    sum.emit("result", s);
11});
12sum.on("result", function (s) {
13    toastLog("sum = " + s + ", 当前线程: " + threads.currentThread());
14});

有关线程的其他问题,例如生产者消费者等问题,请用 Java 相关方法解决,例如java.util.concurrent.BlockingQueue