我已经开始学习多核编程和开发并行算法。这可以通过在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
为什么系统会以不自然的方式运行?
现在,我的问题是:
答案 0 :(得分:2)
我很想知道速度增加的因素。我发现它大约是0.23。
这是因为您的多线程测试无效。它实际上并不测量线程所用的时间。相反,它只是测量启动线程的时间。
其他测试也无效。您没有考虑JVM预热效果......并且测试所做的工作量不足以作为指示。
另一个问题是,读取文件所花费的时间(例如在Linux上)取决于操作系统是否已经缓存它。因此,如果您运行其中一个测试然后再次运行它,您很可能会发现它第二次显着更快!
现在执行时间是:Single Threaded - 1459052.0ns 多线程 - 1768651.0ns
为什么系统会以不自然的方式运行?
这实际上是我期望发生的......对于该版本的基准测试。由于使用两个线程进行读取,创建两个线程的开销似乎超过任何(假设的)加速。
您的问题:
Q1。会增加线程数,减少执行时间吗?
它可能会。这取决于您拥有多少个内核,线程是CPU还是I / O限制,是否存在数据结构或资源争用等等。
Q2。何时应该在编写程序时使用多线程
当考虑性能时,问题可以合理地划分为可以并行执行的子任务。此外,对于小问题,设置线程的开销可能会超过任何可能的性能提升。
Q3。是否可以将相同的文件概念移植到数据库中,其中每个线程根据类别读取数据库的一部分,如新闻,体育,政治等信息将由相应的线程读取,最后结果将被聚集在一起。这可行吗?
也许。
但是,您的(无效)测试可能会让您误解多线程的好处。实际上,任何涉及读取或写入光盘的内容都受到光盘驱动器具有单个读/写"头部"它一次只能进行一次硬件级读写操作。操作系统或数据库系统可以通过各种技巧来提供更快性能的印象,但如果应用程序足够强大,那么就会碰壁。
简而言之,理论上可能只有有限的加速量。
Q4。多线程是否应仅用于CPU绑定程序?
没有。
但这并不意味着多线程应该用于所有事情。
它甚至不应该用于所有CPU绑定程序!
简单的概括不适用。它更复杂。
答案 1 :(得分:0)
线程是一个协助并行执行的概念。很多时候我们看到CPU处于空闲状态,其处理速度远远超过人工或者小代码片段。当我们引入线程时,我们会尝试通过确保它有足够的指令集来执行来减少CPU的空闲时间。
让我们举个例子;
在每笔交易中,我们确实有一些预先& amp;在我们实际进入核心业务逻辑(由CPU执行)之前发布要遵循的基本步骤。在这些活动期间,CPU处于空闲状态。通过多线程,我们确保在实际处理一个线程的同时,另一个线程的前/后活动也同时执行,因此一旦第一个线程的处理结束,就可以采取第二个任务进行处理。
回到下一个问题,我们应该为基本功能而不是核心业务逻辑实现多线程,因为它可能会产生负面影响。
如果可能,我们总是尝试为昂贵的活动引入并行执行(这需要更多时间)。