Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.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 - Fatal编程技术网

Java 多线程环境

Java 多线程环境,java,multithreading,Java,Multithreading,是否有任何指导方针可以知道某个特定程序是否会从多线程中受益 在单线程中,CPU利用率通常较低,如果将程序的不相关部分组成单独的线程,在某些情况下CPU利用率可能会更高。也许当一个线程正在等待I/O时,其他线程可以利用CPU。但是,在一个程序中,有什么东西需要注意,看看它是否会从多线程中受益吗?由于多核CPU的性质,在当今的大多数情况下,程序都会从多线程中受益。单个线程一次只能在一个内核上工作,而多个线程可以分布在多个内核上 更重要的问题是:何时可以使用多线程?哪些任务可以并行化?这通常是不可能的

是否有任何指导方针可以知道某个特定程序是否会从多线程中受益


在单线程中,CPU利用率通常较低,如果将程序的不相关部分组成单独的线程,在某些情况下CPU利用率可能会更高。也许当一个线程正在等待I/O时,其他线程可以利用CPU。但是,在一个程序中,有什么东西需要注意,看看它是否会从多线程中受益吗?

由于多核CPU的性质,在当今的大多数情况下,程序都会从多线程中受益。单个线程一次只能在一个内核上工作,而多个线程可以分布在多个内核上

更重要的问题是:何时可以使用多线程?哪些任务可以并行化?这通常是不可能的,有时甚至是不希望的,因为它在代码中引入了一个很难调试的不可预测元素:竞争条件

是的,如果你的程序在I/O上等待了很长时间,那么你的CPU在这段时间通常是空闲的。如果在此期间您可以使用CPU做些什么,那么它将自然地提高性能;-。即使在单核上


另一个更新:请记住,多线程可能会过度。如果运行的线程多于CPU内核,那么调度程序将不得不在这些线程之间切换,这是一种开销。如果您的线程没有阻塞I/O或其他内容,那么这种开销只是浪费时间。

通常,如果您可以将任务分解为多个独立的子任务,并且您有效地拥有多个处理器来执行任务优化,或者如果您需要保持系统交互,即使阻塞任务,例如,与正在执行的网络读取一样,其他线程可以继续处理用户请求


另一个原因是模拟并行性,即使没有线程那么多的处理器来同时执行多个任务,即使没有实现真正的优化。这就是典型的操作系统所做的,它们并行运行多个程序,即使它们必须给它们很少的时间来交替执行。

多线程通常是一个好主意,因为这样您就可以利用多核的功能。现代CPU通常不会获得更快的内核,而是更多的内核,因此,如果应用程序是多线程的,它将从中受益

正如前面所说的,困难的任务是正确使用多线程。在大多数情况下,您应该专门为多线程设计应用程序。若您有一个单线程的应用程序,并且希望加快速度,那个么您可能会寻找可能被拆分为多个部分的冗长操作,例如,寻找每个迭代都独立于其他部分的循环


但是,请记住,多线程也会带来一些开销,因此单个任务需要一定的最小大小才能有效执行。

要使用多线程,您必须拥有可以同时执行的独立任务。这些需要不繁琐,理想情况下长度至少为10微秒,否则使用多线程的开销可能高于使用多线程的优势

若您的进程是IO绑定的,那个么即使只有一个内核,它也可以从使用多个线程中获益。如果您的进程是CPU受限的,那么您必须有空闲的内核来提高性能

一个CPU受限的进程所能得到的最大改进等于内核的数量。i、 e.如果你有N个核,它可以快N倍。这假设您至少可以执行N个独立任务

通常,优化代码可以使您的应用程序运行得更快,而无需进行重大更改。。我通过修改代码所做的最大改进是比以前的实现好1000倍。出于这个原因,您的第一步应该是对您的系统进行概要分析,看看它是否可以改进。之后考虑多线程应用程序。 将工作传递给另一个线程并不是一件小事,尤其是在传递少量大型任务时。队列可以处理高吞吐量,但如果您想在最短的时间延迟内完成任务,这很重要

这是在2.3 GHz T4500上运行的。传递的数据量很小,当您在线程之间访问更多数据时,所需的时间就越长

ExecutorService es = Executors.newCachedThreadPool();
for(int i=0;i<20;i++) {
    Thread.sleep(10);
    Future<Long> future = es.submit(new Callable<Long>() {
        long start = System.nanoTime();
        public Long call() throws Exception {
            return start;
        }
    });
    System.out.printf("Took %.1f us to submit/get%n", 
        (System.nanoTime() - future.get())/1e3);
}
es.shutdown();

请注意其他海报提供的答案,我想补充几点:

1必须处理需要超时和/或延迟的多个操作的应用程序。多线程可以消除复杂且难以调试的状态机,线程实际上是操作系统运行的状态机。一个明显的例子是多通道通信应用程序,它需要延迟来实现特定的协议-睡眠比所有计时器、回调等都更容易实现、理解和调试,而不是感染单线程 需要此功能的应用程序。为每个通道运行单独的线程允许“在线”编写此类代码。一旦你有一个通道工作,100是没有问题的

2个需要API的应用程序被阻止。无论如何,在Windows上有一些API会阻塞,并且没有异步替代方案,尤其是在旧操作系统上。如果没有专用线程来调用这些,您将陷入困境

3个应用程序,在这些应用程序中,多线程解决方案看起来会更快,但提供的成本/性能优势不足以使其发挥价值。明年,情况将有所不同

4个应用程序是大型系统的一部分,并且打印的需求规格大于~100g,开始考虑多线程

5如果应用程序很琐碎,不受时间限制,而且你几乎没有线程体验,那么不管怎样,只要好玩,就把它的一部分线程掉。过一段时间,你就会知道如何构建大型、复杂的应用程序,以便它们能够可靠地工作,并且可以维护和扩展“我不做多线程”在面试中表现不佳:

Rgds,
马丁

好的。实际上,我的程序使用了很多for循环来比较两个不同的集合。关于改进这样的程序有什么建议吗?除非你比较10000个元素,否则使用一个线程可能会更快。如果可能的话,我假设您使用的是原语而不是包装器。我的一些集合由自定义对象组成。进行所有比较需要多长时间。理想情况下,您应该能够将其分解为大约需要100微秒或更长时间的任务。@aps您可以在插入/删除元素之前或之后在代码中执行某些操作。但对你来说,这可能不是一个好主意,这取决于你实际上在做什么。
Took 61.1 us to submit/get
Took 45.1 us to submit/get
Took 49.1 us to submit/get
Took 37.9 us to submit/get
Took 58.5 us to submit/get