gpt4 book ai didi

java - Java I/O 中的多线程是否受限于(或)CPU 受限

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:20:52 31 4
gpt4 key购买 nike

我已经开始学习多核编程和开发并行算法。这可以通过在 Java 中使用多线程轻松完成。因此,我创建了两个包含 10 行内容的文本文件,如下所示:

This is the first line in file 1
This is the second line in file 1
This is the third line in file 1
This is the fourth line in file 1
This is the fifth line in file 1
This is the sixth line in file 1
This is the seventh line in file 1
This is the eighth line in file 1
This is the ninth line in file 1
This is the tenth line in file 1

同样,在另一个文本文件中,文件 1 被替换为 文件 2。我写了一个程序来读取文件的内容,有和没有线程。它们如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class SimpleThread {

static void printFile(BufferedReader br) throws Exception
{
for(String line; (line = br.readLine())!=null; )
System.out.println(line);
}

public static void main(String args[]) throws Exception
{
double startTime = System.nanoTime();
BufferedReader br1 = new BufferedReader(new FileReader(new File("test1.txt")));
BufferedReader br2 = new BufferedReader(new FileReader(new File("test2.txt")));
SimpleThread.printFile(br1);
SimpleThread.printFile(br2);
System.out.println(System.nanoTime() - startTime + "ns");
}
}

使用多线程的程序如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class Threading extends Thread{

BufferedReader br;

public Threading(String fileName)
{
try{
br = new BufferedReader(new FileReader(new File(fileName)));
start();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}

private void printFile(BufferedReader br) throws Exception
{
for(String line; (line = br.readLine())!=null; )
System.out.println(line);
}

public void run()
{
try{
printFile(br);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}

public static void main(String args[]) throws Exception
{
double startTime = System.nanoTime();
Threading t1 = new Threading("test1.txt");
Threading t2 = new Threading("test2.txt");
System.out.println(System.nanoTime() - startTime + "ns");
}
}

现在,当我比较这两个程序的执行时间时,我发现单线程程序需要 1544589.0ns,而多线程程序需要 410522.0ns

我很想知道速度提高的因素。我发现它大约是 0.23

修改多线程代码后,发现单线程程序执行速度更快,这更大程度上增加了我的困惑。

修改后的代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

public class Threading extends Thread{

BufferedReader br;

public Threading(String fileName)
{
try{
br = new BufferedReader(new FileReader(new File(fileName)));
start();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}

private void printFile(BufferedReader br) throws Exception
{
for(String line; (line = br.readLine())!=null; )
System.out.println(line);
}

public void run()
{
try{
printFile(br);
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}

public static void main(String args[]) throws Exception
{
double startTime = System.nanoTime();
Threading t1 = new Threading("test1.txt");
Threading t2 = new Threading("test2.txt");
t1.join(); //waiting for t1 to finish
t2.join(); //waiting for t2 to finish
System.out.println(System.nanoTime() - startTime + "ns");
}
}

现在执行时间是:单线程 - 1459052.0ns
多线程 - 1768651.0ns

为什么系统表现不自然?

现在,我的问题是:

  1. 增加线程数会减少执行时间吗?
  2. 什么时候应该在编写程序时使用多线程
  3. 能否将文件的相同概念移植到数据库中,其中每个线程根据类别读取数据库的一部分,例如新闻、体育、政治等信息将由相应的线程读取,最后结果将聚在一起。这可行吗?
  4. 多线程应该只用于 CPU 密集型程序吗?

最佳答案

I was curious to know the factor by which the speed was increased. I found it to be 0.23 approximately.

那是因为你的多线程测试无效。它实际上并不测量线程所花费的时间。相反,它只是测量启动线程的时间。

另一个测试也无效。您没有考虑 JVM 预热效果......并且测试所做的工作量不足以指示。

另一个问题是读取文件(例如在 Linux 上)所花费的时间取决于操作系统是否已经缓存了它。因此,如果您运行其中一个测试然后再次运行它,您很可能会发现第二次运行速度明显加快!

And now the execution time are : Single Threaded - 1459052.0ns Multithreaded - 1768651.0ns

Why is the system behaving in an unnatural way?

这实际上是我期望发生的......对于那个版本的基准测试。似乎创建两个线程的开销超过由于使用两个线程读取而产生的任何(假设的)加速。


您的问题:

Q1. Will increasing the number of threads, reduce the execution time?

也许可以。这取决于您有多少个内核,线程是受 CPU 还是 I/O 限制,是否存在数据结构或资源争用等等。

Q2. When should one use multi-threading in writing programs

当性能是一个问题时,问题可以合理地划分为可以并行执行的子任务。此外,对于小问题,设置线程的开销可能超过任何可能的性能提升。

Q3. Can the same concept of file be ported to databases, where every thread reads a portion of the database based on the category say information on news, sports, politics, etc. will be read by the corresponding threads and finally the results will be clubbed together. Is this feasible?

也许吧。

但是,您的(无效的)测试可能会让您误导多线程的好处。实际上,任何涉及读取或写入磁盘的操作都受到以下事实的限制:磁盘驱动器只有一个读/写“磁头”,并且一次只能执行一个硬件级别的读取或写入操作。操作系统或数据库系统可以使用各种技巧来给人以更快性能的印象,但如果应用程序足够努力,你就会碰壁。

简而言之,理论上可能实现的加速是有限的。

Q4. Should multi-threading be used only for CPU bound programs?

没有。

但这并不意味着多线程应该用于所有事情。

它甚至不应该用于所有受 CPU 限制的程序!

简单的概括并不适用。它要复杂得多。

关于java - Java I/O 中的多线程是否受限于(或)CPU 受限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29442743/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com