首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java:通过从另一个线程以某种方式信令,从主线程调用一个方法

Java:通过从另一个线程以某种方式信令,从主线程调用一个方法
EN

Stack Overflow用户
提问于 2015-09-02 03:11:26
回答 4查看 1.4K关注 0票数 1

我有一个有两个线程的应用程序( main和另一个线程t1),它们共享一个易失性变量myVar. )。对于如何使main线程通过从t1发出信号来调用方法t1,有什么想法吗?我使用ChangeListener实现了它,并且在myVar更改时调用了myMethod,但是该方法是从t1调用的,而不是从主线程调用的(注意:我需要从主线程调用该方法,因为这是对Java的JavaScript代码的调用,因此出于安全原因,只有主线程可以这样做)。提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-09-02 03:33:48

您必须在某个标量上循环主线程,我建议使用java提供的一个Atomics (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html),但是如果您想要的话,可以使用volatile。

每个线程只能按顺序运行--这只是计算的工作方式。处理这个问题的方法是,当主线程在某种类型的循环中旋转时,最终检查您的标量是否已经设置,当它设置了时,您希望取消变量并执行您的JavaScript。在这段代码中,我认为与使用compareAndSet操作相比,Atomics有一个优势,因为如果您试图检查一个操作中的值,然后在另一个操作中再次设置它,这意味着您可能会错过对JS的调用,因为另一个线程会在主线程之间设置变量,从而检查它和设置变量(尽管variable的使用可能被解释为我的观点)。

代码语言:javascript
复制
//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每次T1将foo设置为true时调用JS,则必须在T1中阻塞,直到main取消了foo,或者使用AtomicInteger来计算T1设置foo的次数--这取决于您的需要。

票数 3
EN

Stack Overflow用户

发布于 2015-09-02 03:26:49

由于两个线程都共享同一个myVar实例,所以可以使两个线程在共享变量上进行同步。让main在执行myMethod之前等待myVar通知。稍后,t1可以通过变量myVar通知,等待线程可以继续并继续进行方法调用。

下面的片段充分展示了这个想法

代码语言:javascript
复制
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();
            }
        }
    };

}

输出是

代码语言:javascript
复制
[main] Waiting for t1 to notify...
[t1] sleep for 1 sec
[t1] Notifying sharedObject so Main can invoke myMethod
[main] executing main method
MyMethodInfoked.
票数 0
EN

Stack Overflow用户

发布于 2015-09-02 03:35:42

您可以使用等待/通知块来防止主线程继续运行,直到发出信号。

代码语言:javascript
复制
static Main main = // ...
static boolean signal = false;

// t1:
// Do work
signal = true;
synchronized (main) {
    main.notify();
}

// main:
synchronized (main) {
    while (!signal) {
        main.wait();
    }
}

myMethod();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32344071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档