Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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
JavaFX任务可调用_Java_Multithreading_Javafx - Fatal编程技术网

JavaFX任务可调用

JavaFX任务可调用,java,multithreading,javafx,Java,Multithreading,Javafx,我正在开发一个JavaFX应用程序,并在ExecutorServicesubmit方法中提供JavaFX任务。此外,我还试图在Future对象中提交的返回值中获取任务的返回值。然后我发现ExecutorService只在提交Callable对象时返回值,尽管有call方法,JavaFX任务仍然可以运行。那么,这个问题有什么解决办法吗 我试着用这种方式解决了我的问题,但当我不想写自己的课程时,我愿意接受建议 我的主要方法是: public static void main(String[] arg

我正在开发一个JavaFX应用程序,并在ExecutorService
submit
方法中提供JavaFX任务。此外,我还试图在
Future
对象中提交的返回值中获取
任务的返回值。然后我发现
ExecutorService
只在提交
Callable
对象时返回值,尽管有
call
方法,JavaFX任务仍然可以运行。那么,这个问题有什么解决办法吗

我试着用这种方式解决了我的问题,但当我不想写自己的课程时,我愿意接受建议

我的主要方法是:

public static void main(String[] args) throws InterruptedException, ExecutionException {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    Semaphore semaphore = new Semaphore(1);
    List<Integer> list = IntStream.range(0,100).boxed().collect(Collectors.toList());
    Iterator<Integer> iterator = list.iterator();
    while (iterator.hasNext()){
        List<Integer> sendingList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            sendingList.add(iterator.next());
        }
        System.out.println("SUBMITTING");
        Future<Integer> future = executorService.submit((Callable<Integer>) new TestCallable(sendingList,semaphore));
        System.out.println(future.get());
        semaphore.acquire();
    }
    executorService.shutdown();
    System.out.println("COMPLETED");
}

Task
扩展了
java.util.concurrent.FutureTask
,从而实现了
Future
接口。这意味着您可以像使用未来任务一样使用任务

Executor executor = ...;
Task<?> task = ...;
executor.execute(task);
task.get(); // Future method

如果您不需要
Task
提供的功能,那么最好直接使用
Runnable
Callable

这里不太清楚您想做什么

首先,您的
信号量
不起任何作用,因为您使用了
Executors.newSingleThreadExecutor()
,它已经保证在任何时间点只能运行一个任务

其次,正如@Slaw所提到的,您可能会阻塞JavaFX应用程序线程,这取决于您的实际实现(您的示例实际上不是JavaFX应用程序)

接下来,
ExecutorService
submit()
提供了两个主要重载

第一个重载接受一个
可调用的
。此重载允许您检索
Callable
(通过在返回的
Future
上调用
get()
)返回的值,因为
Callable
指的是可以调用的内容-它可以返回值

第二个重载接受一个
可运行的
。由于
Task
实现了
Future
RunnableFuture
接口,并且
Future
RunnableFuture
接口扩展了
RunnableFuture
接口,因此传入
Task
相当于调用此重载。此重载不希望返回结果,因为
Runnable
是在没有结果的情况下运行的东西。在此重载返回的
Future
上调用
get()
将被阻止,直到任务完成,并且
null
将被返回。如果需要检索由
任务返回的值,则需要调用
任务的
get()
,而不是由
ExecutorService.submit()返回的
Future

根据OP的评论进行编辑 首先,由于调用方法已经在后台线程中运行,并且所有任务都应该按顺序(而不是并行)运行,因此您应该在不使用所有这些额外的
ExecutorService
Task
的情况下运行它们,除非有其他原因必须这样做


其次,
列表
对象只不过是一个进行引用的对象。真正影响性能的是,您正在将元素的引用复制到新列表中。如果索引已知,则可以使用,因为返回的列表将使用与原始列表相同的支持数组,因此没有额外的
O(n)
复制操作。

您确实注意到a)
任务
实现
未来
b)提交任务并立即调用
get
会导致在调用中等待并等待任务完成。你可以直接在线程上执行任务。如果我有一个多线程执行器,如果没有可用线程,我想等待,而不是每个任务?调用
Future.get
确保等待任务完成。假设提交线程和执行任务的线程具有相同的优先级,则在不同线程上运行任务不会更快,并且不会导致任何任务并行运行,即使使用多线程执行器也是如此。在这种情况下,提交任务会将工作从一个线程移动到另一个线程,并使提交任务在等待任务完成时保持忙碌……我的信号灯在那里,确保我在准备运行新线程之前创建每个子列表。在我的实际应用程序中,列表要大得多,提交它们会占用大量内存并阻塞CPU。此外,在我的应用程序中,我在另一个后台守护进程线程上运行executor,因此它不会冻结我的GUI。这只是一个测试代码。“因为
Task
实现了
Future
接口,而
Future
接口扩展了
Runnable
接口…”<代码>未来
不扩展
可运行
。我相信您正在考虑
RunnableFuture
(它是通过扩展
FutureTask
实现的
Task
)。
Executor executor = ...;
Task<?> task = ...;
executor.execute(task);
task.get(); // Future method
Executor executor = ...;
Task<?> task = ...;
task.setOnSucceeded(event -> handleResult(task.getValue()));
task.setOnFailed(event -> handleException(task.getException()));
executor.execute(task);