我有一个包含2个主题的应用程序( main
和另一个主题 t1
),它共享一个易变量 {{ 1}} 即可。有关如何通过myVar
以某种方式发出信号,让main
主题调用方法 myMethod
的任何想法?
我通过使用ChangeListener实现它,当myVar更改时调用myMethod,但是从 t1 调用方法,而不是从主线程调用(注意:我需要从主线程调用此方法,因为这是从Java调用JavaScript代码,因此出于安全原因,只有主线程可以这样做)。提前致谢。
答案 0 :(得分:1)
你必须让你的主线程在某个标量的循环中旋转,我会推荐一个java提供的Atomics(http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html),但你可以使用volatile,如果你想的话我认为。
每个线程只能按顺序运行 - 它只是计算的工作方式。处理这个问题的方法是,当主线程在某种循环中旋转时,你最终会检查是否已经设置了你的这个标量,当它有,你想要取消设置变量并执行你的JavaScript。在这段特殊的代码中,我认为使用compareAndSet操作时,Atomics优于volatile,因为如果你试图在一个操作中检查值然后设置volatile,那么使用volatile会让你在线程之间陷入困境。它又在另一个操作中给了另一个线程足够的时间再次设置它 - 这意味着你可能会错过对JS的调用,因为另一个线程在主线程检查它并设置它之间设置变量(尽管使用volatile和Atomics)可能会被解释为我的观点。)
//main thread
AtomicBoolean foo = new AtomicBoolean(false);
while (...somecondition...){
if(foo.compareAndSet(true, false)){
//execute JS
}
//do some other work
}
在T1线程中,只需拨打foo.set(true)
。
如果你希望main为你的JS调用每个时间T1将foo
设置为true,那么你必须在T1中阻塞,直到main取消设置foo,或者使用{{ 1}}计算T1设置foo的次数 - 取决于您的需要。
答案 1 :(得分:0)
由于两者都共享同一个myVar
实例,因此可以使两个线程同步共享变量。在执行main
之前让myVar
等待myMethod
通知。稍后,t1
可以通过变量myVar
进行通知,等待的线程可以继续并继续进行方法调用。
以下代码段充分展示了这个想法
public class MainPlay {
public static void main(String[] args) {
MainPlay mp = new MainPlay();
mp.execute();
}
public void execute() {
Thread main = new Thread(mainRunnable, "main");
Thread t1 = new Thread(t1Runnable, "t1");
main.start();
t1.start();
}
public Object myVar = new Object();
public void myMethod() {
System.out.println("MyMethodInfoked.");
}
public Runnable t1Runnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[t1] sleep for 1 sec");
Thread.sleep(1000);
System.out.println("[t1] Notifying myVar so Main can invoke myMethod");
myVar.notify();
} catch (InterruptedException e) {
// interupted.
}
}
}
};
public Runnable mainRunnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[main] Waiting for t1 to notify...");
myVar.wait();
} catch (InterruptedException e) {
// interrupted.
}
System.out.println("[main] executing main method");
myMethod();
}
}
};
}
输出
[main] Waiting for t1 to notify...
[t1] sleep for 1 sec
[t1] Notifying sharedObject so Main can invoke myMethod
[main] executing main method
MyMethodInfoked.
答案 2 :(得分:0)
您可以使用wait / notify块来阻止主线程继续,直到发出信号为止。
static Main main = // ...
static boolean signal = false;
// t1:
// Do work
signal = true;
synchronized (main) {
main.notify();
}
// main:
synchronized (main) {
while (!signal) {
main.wait();
}
}
myMethod();
答案 3 :(得分:0)
如果主线程没有别的办法,@ searchengine27提出的方法会导致该线程产生不必要的处理器负载。
因此,与一些AtomicXXX
类相比,最好使用一些blocking queues,它允许从一个线程(带put()
)写入数据并消耗该数据另一个。如果这样的队列为空而不使用任何CPU资源,主队列将阻塞(通过调用take()
方法)。