Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Java实现跨线程函数调用_Java_Multithreading_Function - Fatal编程技术网

用Java实现跨线程函数调用

用Java实现跨线程函数调用,java,multithreading,function,Java,Multithreading,Function,我想知道如何在Java中跨线程调用不同的函数。现在我要做的就是编写线程的run()函数 public volatile boolean invokeMyFunction = false; public void run() { while(true) { if(invokeMyFunction) { MyFunction(); invokeMyFunction = false; } } } 如果

我想知道如何在Java中跨线程调用不同的函数。现在我要做的就是编写线程的run()函数

public volatile boolean invokeMyFunction = false;

public void run() {
    while(true) { 
        if(invokeMyFunction) {
            MyFunction();
            invokeMyFunction = false;
        }
    }
}

如果我想从该线程外部运行函数MyFunction(),请编写“whateverobject.invokeMyFunction=true”,它将从该线程内部运行我的函数,因为该循环将拾取它。这对我来说非常好,但由于while(true)循环,它使用了100%的CPU。我可以通过打一个线程来解决这个问题。在循环中睡眠(1000),但这看起来很混乱,我不得不相信有更好的方法来解决这个问题。

你可以在线程中放置一个监视器,然后等待监视器。当你调用函数时,告诉监视器释放一个可以运行你的函数的人(它应该只有这个人),然后再返回等待

另一方面,睡眠方式本身也没有什么问题。我明白为什么您会称之为混乱,但它会降低犯愚蠢错误的可能性,并提供服务之间更松散的耦合


(旁注-您不需要在线程中放置监视器。您可以使用该对象作为监视器,而不是内部监视器。但是,如果您向可能干扰它的其他人开放自己,那么最好使用私有内部对象作为监视器。)

您的方案对我来说很奇怪。为什么要启动一个线程,但让它等到将来某个未知的时间才能运行?为什么不晚一点开始呢

添加编辑以澄清glowcoder


删除编辑-我的错,我误解了他的问题,他希望能够多次调用我的函数。在这种情况下,他应该使用其他答案中建议的某种队列,除了占用cpu这一事实之外,代码中还有几个漏洞

如果您的其他线程希望此线程在执行
MyFunction
所需的时间内调用两次该怎么办?你最终会错过一次调用

一个改进可以是:

public volatile boolean invokeMyFunction = false;

public void run() {
    while(true) { 
        if(invokeMyFunction) {
            // Moved here.
            invokeMyFunction = false;
            MyFunction();
        }
    }
}
然而,这只会降低比赛条件的可能性,而不是不可能


您最好像我建议的那样使用
阻塞队列
。让另一个线程在该线程读取的队列中发布一些内容。您也不会这样占用cpu。

我认为在这里,实现这一点的最简单和cpu友好的方法是

public void run() {
    while(true) { 
        synchronized(foo) {
            while(!invokeMyFunction) {
                foo.wait();
            }
        }
        MyFunction();
        invokeMyFunction = false;
    }
}
上面的代码在它自己的线程中运行。另一个线程可以这样做,让第一个线程运行MyFunction():

注意 a) 您不能将invokeMyFunction设置为布尔值并通过它进行同步,因为在所有java中只有两个布尔值:) b) 如果将invokeMyFunction设置为n次,则如果invokeMyFunction设置为true而不是false,则它的运行次数可能会更少。 c) 使用BlockingQueue可能更容易,并允许线程1运行任意函数:

while(true) {
    Runnable next = queue.take();
    next.run()
}
另一个线程会告诉它像这样运行MyFunction:

queue.put(new Runnable() {
    void run() {
        MyFunction();
    }
});
对我来说似乎更容易:)另外,如果您希望n个线程运行队列中的任何内容,那么您只需要生成n个线程来侦听队列。或者,您可以学习如何使用线程池:

注意:


queue.put()阻塞,直到BlockingQueue中有新的可用空间,即如果空间“已满”,则阻塞。请参阅您正在使用的任何BlockingQueue实现的实现文档,以查看您的队列是否有限制。在任何情况下,请确保添加的项目不会超过您可以处理的时间。

是否可能有多个函数调用?您是否需要一个可以在第二个线程上调用任意数量函数的解决方案?理想情况下,我喜欢一个允许在第二个线程上对多个函数进行多次调用的解决方案,是的,另一个操作可能需要一段特定的时间才能完成,最好不要阻止主线程执行。例如,考虑读取一个feed或socket通信。不需要阻止,您仍然可以在另一个线程中运行其他操作。只是在准备好之前不要启动它。也许不会,但是每次都必须启动一个新线程,或者使用线程池或执行器服务。我并不完全反对,因为这些都是值得学习的东西,但它们不在问题的范围之内。优雅而简单的实现,正是我想要的-谢谢:)
queue.put(new Runnable() {
    void run() {
        MyFunction();
    }
});