Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/sharepoint/4.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,我想做一个我已经完成的任务,除了这次使用多线程。我必须从一个文件(逐行)中读取大量数据,从每行中获取一些信息,然后将其添加到地图中。该文件的长度超过一百万行,因此我认为它可能受益于多线程 我不确定我的方法,因为我以前从未在Java中使用过多线程。 我想让main方法进行读取,然后将已读取的行提供给另一个线程,该线程将格式化一个字符串,然后将其提供给另一个线程以放入映射 public static void main(String[] args) { //Some information

我想做一个我已经完成的任务,除了这次使用多线程。我必须从一个文件(逐行)中读取大量数据,从每行中获取一些信息,然后将其添加到地图中。该文件的长度超过一百万行,因此我认为它可能受益于多线程

我不确定我的方法,因为我以前从未在Java中使用过多线程。 我想让main方法进行读取,然后将已读取的行提供给另一个线程,该线程将格式化一个字符串,然后将其提供给另一个线程以放入映射

public static void main(String[] args)
{
    //Some information read from file
    BufferedReader br = null;
    String line = '';
    try {
        br = new BufferedReader(new FileReader("somefile.txt"));
        while((line = br.readLine()) != null) {
            // Pass line to another task
        }


    // Here I want to get a total from B, but I'm not sure how to go about doing that

}


public class Parser extends Thread
{
    private Mapper m1;

    // Some reference to B
    public Parse (Mapper m) {
        m1 = m;
    }

    public parse (String s, int i) {
        // Do some work on S
        key = DoSomethingWithString(s);
        m1.add(key, i);
    }

}

public class Mapper extends Thread
{
    private SortedMap<String, Integer> sm;
    private String key;
    private int value;
    boolean hasNewItem;

    public Mapper() {
        sm = new TreeMap<String, Integer>;
        hasNewItem = false;
    }

    public void add(String s, int i) {
        hasNewItem = true;
        key = s;
        value = i;
    }

    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                if (hasNewItem) {
                    // Find if street name exists in map
                    sm.put(key, value);
                    newEntry = false;
                }   
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        // I'm not sure how to give the Map back to main. 
    }
}
publicstaticvoidmain(字符串[]args)
{
//从文件中读取的一些信息
BufferedReader br=null;
字符串行=“”;
试一试{
br=新的BufferedReader(新的文件阅读器(“somefile.txt”);
而((line=br.readLine())!=null){
//将行传递给另一个任务
}
//这里我想从B得到一个总数,但我不知道该怎么做
}
公共类解析器扩展线程
{
私有映射器m1;
//对B的一些参考
公共解析(映射器m){
m1=m;
}
公共解析(字符串s,int i){
//做一些工作,使其更健康
key=DoSomethingWithString;
m1.添加(键,i);
}
}
公共类映射器扩展线程
{
私有分类地图sm;
私钥;
私有int值;
布尔hasNewItem;
公共映射器(){
sm=新树形图;
hasNewItem=false;
}
公共void add(字符串s,int i){
hasNewItem=true;
键=s;
值=i;
}
公开募捐{
而(!Thread.currentThread().isInterrupted()){
试一试{
如果(hasNewItem){
//查找地图中是否存在街道名称
sm.put(键、值);
newEntry=false;
}   
}捕捉(中断异常e){
Thread.currentThread().interrupt();
}
}
//我不知道如何把地图还给梅因。
}
}
我不确定我是否采取了正确的方法。我也不知道如何终止映射程序线程并在main中检索映射。我将有多个映射程序线程,但我在上面的代码中只实例化了一个

我还刚刚意识到我的Parse类不是一个线程,而是另一个类,如果它不重写run()方法,那么我认为Parse类应该是某种队列

还有想法?谢谢

编辑:
感谢所有的回复。似乎由于I/O将是主要的瓶颈,因此并行化对效率没有什么好处。但是,出于演示目的,我是否走上了正确的道路?我仍然有点担心不知道如何使用多线程。

通常I/O所用的时间比内存中的ta要长得多我们把这类工作称为I/O绑定。并行性最多只能有一点改进,实际上会使事情变得更糟

你当然不需要一个不同的线程来把东西放到地图上。除非你的解析非常昂贵,否则你也不需要一个不同的线程

如果您有其他线程来执行这些任务,那么他们可能会花费大部分时间坐在那里等待下一行被读取

即使并行化I/O也不一定会有帮助,而且可能会造成伤害。即使您的CPU支持并行线程,您的硬盘也可能不支持并行读取

编辑:

我们所有对此发表评论的人都认为任务可能是I/O绑定的,因为这通常是正确的。然而,从下面的评论来看,这个案例是个例外。更好的答案应该包括下面的第四条评论:


测量在不处理文件中所有行的情况下读取它们所需的时间。与读取和处理它们所需的时间进行比较。这将为您节省多少时间提供一个宽松的上限。这可能会因为线程同步的新成本而降低


为什么您需要多线程?您只有一个磁盘,而且它只能运行得很快。在这种情况下,多线程几乎肯定不会有帮助。如果有,从用户的角度来看,它将是非常小的。多线程不是您的问题。从大文件读取是您的瓶颈。

您可能希望读取。因为我们的工作是严格的串行(IO)的,通过多线程处理剩下的部分,您将获得微不足道的改进。当然不值得为创建水密多线程代码而付出代价


也许你应该寻找一个新的玩具示例来并行化。

从文件中读取是你代码的瓶颈。多线程在这里没有帮助。在这里使用多线程可能会让你措手不及。正如@hovercraftfullofels所指出的,你的线程可以比磁盘IO速度快得多。你打算如何管理要读取的线程ads有多少行。如果一个或多个线程由于某种不可预见的原因失败了怎么办?我建议您在一个线程中处理一个文件,并根据手头的机器选择一种处理方法。如果您有一个具有128 Gig ram的服务器,将其读入内存,然后进行处理,如果不是逐行处理的话。这是真的,我的大Gest瓶颈肯定是从文件中读取。让一个线程不断地从IO中读取,而另一个线程进行解析并将项目放入地图,这会有助于提高速度吗?为了演示起见,我可以用上面的方法进行任何改进吗?我明白这不会有多大帮助,而且可能不值得尝试特别是对于生产代码,我还是很好奇。所以最好是串行地完成这一切?如果您确实从将读取和处理分为两个线程中得到了一些改进,那么它可能会很小,但代价是开发时间/风险更大,maintai的代码更复杂