Java I/O中的多线程绑定(或)CPU绑定吗

Java I/O中的多线程绑定(或)CPU绑定吗,java,multithreading,Java,Multithreading,我已经开始学习多核编程和开发并行算法。这可以通过在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 si

我已经开始学习多核编程和开发并行算法。这可以通过在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
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");
    }
}
类似地,在另一个文本文件中,文件1替换为文件2。我写了一个程序来读取文件的内容,有线程和没有线程。详情如下:

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
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");
    }
}
使用多线程的程序如下所示:

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
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

为什么系统会以一种不自然的方式运行

现在,我的问题是:

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

  • 线程是一个有助于并行执行的概念。很多时候,我们看到CPU是空闲的,它的处理速度比人或小代码片段要快得多。当我们引入线程时,我们试图通过确保CPU有足够的指令集来执行来减少CPU的空闲时间

    让我们举一个例子

    在每个事务中,在我们真正进入核心业务逻辑(由CPU执行)之前,我们确实要遵循一些基本的前后步骤。在这些活动期间,CPU处于空闲状态。使用多线程时,我们确保在实际处理一个线程时,另一个线程的前/后活动也会同时执行,因此,在第一个线程的处理完成后,可以立即执行第二个任务进行处理

    关于下一个问题,我们应该为基本功能而不是核心业务逻辑实现多线程,因为它可能会产生不利影响

    如果可能的话,我们总是尝试为昂贵的活动引入并行执行(这需要更多的时间)

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

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

    另一个测试也是无效的。您没有考虑JVM预热效应。。。而且测试所做的工作量还不足以说明问题

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

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

    为什么系统会以一种不自然的方式运行

    这实际上是我期望发生的事情。。。。对于该版本的基准。由于使用两个线程进行读取,创建两个线程的开销似乎超过了任何(假设的)加速


    你的问题:

    问题1。增加线程数会减少执行时间吗

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

    问题2。什么时候应该在编写程序时使用多线程

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

    第三季度。是否可以将相同的文件概念移植到数据库中,其中每个线程根据类别读取数据库的一部分,例如,新闻、体育、政治等信息将由相应的线程读取,最后结果将合并在一起。这是否可行

    也许吧

    然而,您的(无效)测试可能会让您对多线程的好处产生误解。实际上,任何涉及对光盘进行读写的操作都受到以下事实的限制:光盘驱动器只有一个读写“磁头”,一次只能执行一个硬件级读写操作。操作系统或数据库系统可以使用各种技巧来提高性能,但如果应用程序的推动力度足够大,就会撞上那堵墙

    简言之,理论上可能的加速量是有限的

    第四季度。多线程应该只用于CPU绑定的程序吗

    没有

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

    它甚至不应该用于所有CPU绑定的程序


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

    您的多线程程序不会等到工作线程完成任务后才报告运行时。根据情况,有很多优点和缺点,因此我认为您应该阅读一些有关mu的书籍