java – 什么时候线程超出范围?

我编写了一个程序,可以在文本中计算行,字和字符:它使用线程执行此操作.它有时候很好,但是其他时候不是很好.最终发生的事情是指向字数和变数的变量有时候会变短,有时候不会.

在我看来,线程有时会结束,然后才能对所有想要的单词或字符进行计数.是因为当while(true)循环中断时,这些线程超出范围?

我已经从我的问题的一部分中包含了代码

private void countText() {
  try {
    reader = new BufferedReader(new FileReader("this.txt"));
    while (true) {
      final String line = reader.readLine();
      if(line == null) {break;}
      lines++;
      new Thread(new Runnable() {public void run() {chars += characterCounter(line);}}).start();
      new Thread(new Runnable() {public void run() {words += wordCounter(line);}}).start();
      println(line);
    }

  } catch(IOException ex) {return;}

}

(子问题:这是我第一次询问某些东西和发布的代码,我不想使用StackOverflow代替谷歌和维基百科,我担心这不是一个适当的问题,我试图使问题更一般,所以我不只是要求帮助我的代码…但是,另一个网站,这种问题可能更适合?)

解决方法

不同的线程设计可以更容易地找到并解决这种问题,并且更有效地进行讨价还价.这是一个很长的回应,但是总结是“如果你在Java中做线程,尽可能快地查看 java.util.concurrent”).

我想你是多线程的这个代码学习线程,而不是加速计数字,但这是一个非常低效的方式使用线程.您每行创建两个线程 – 一千行线文件的两千线程.创建线程(在现代JVM中)使用操作系统资源,通常相当昂贵.当两个 – 更不用说两千线程必须访问共享资源(例如你的字符和单词计数器)时,所产生的内存争用也会伤害性能.

使计数器变量同步为Chris Kimpton suggests或Atomic为WMR suggests可能会修复代码,但也会使竞争的影响更糟.我确定它会比单线程算法慢.

我建议只有一个长寿命的线程,它照顾着chars,一个用于单词,每个线程都有一个工作队列,您可以在每次要添加新的数字时向其提交作业.这样只有一个线程正在写入每个变量,如果您对设计进行了更改,那么更明确的是谁负责什么.它也会更快,因为没有内存争用,你不会在紧缩的循环中创建数百个线程.

读取文件中的所有行后,等待所有线程完成之后,才能真正打印出计数器的值,否则丢失尚未完成的线程的更新也很重要.使用您当前的设计,您将必须构建一个您创建的线程的大列表,并通过它来完成它们的检查,以确定它们全部死亡.使用队列和工作线程设计,您可以告诉每个线程排除队列,然后等待直到完成.

Java(从1.5及更高版本)使这种设计非常容易实现:查看java.util.concurrent.Executors.newSingleThreadExecutor.它还使以后更容易添加更多并发(假设正确的锁定等等),因为您只需切换到线程池,而不是单线程.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...