多线程循环批量处理以及多线程操作文件写入相关思路

简介:

经过了一番思考,我觉得可以这样想:对于一个循环的连续数字段,我们可以在给定线程数时,就将这一段数字平均分配给每个线程,因此每个线程只需要按步处理它的任务就行。因为没有跟其他线程的数据发生耦合,所以就可以保证每个数字都只被处理一次,同时在文件写入时也不会出现问题。


接下来,我按照这个思路写了一段测试代码,完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package  thread;
 
import  java.io.BufferedWriter;
import  java.io.File;
import  java.io.FileWriter;
import  java.io.IOException;
 
public  class  Test1 {
 
     public  static  void  main(String[] args) {
         long  millis1 = System.currentTimeMillis();
         int  threadNum =  5 // 测试用的线程数目
         String fileName =  "C:\\Users\\Administrator\\Desktop\\测试1.txt" // 文件名
         for  ( int  i =  0 ; i < threadNum; i++) {
             MyThread myThread =  new  MyThread(i, threadNum, fileName);
             Thread tempThread =  new  Thread(myThread);
             tempThread.setName( "线程"  + i);
             tempThread.start();
         }
 
         long  millis2 = System.currentTimeMillis();
         System.out.println(millis2 - millis1);   //大约1-2ms
     }
 
}
 
/**
  * 自定义线程
  * */
class  MyThread  implements  Runnable {
     private  int  i;  // 第几个线程
     private  int  threadNum;  // 总共创建了几个线程
     private  String fileName;   //文件名
 
     public  MyThread( int  i,  int  threadNum, String fileName) {
         this .i = i;
         this .threadNum = threadNum;
         this .fileName = fileName;
     }
 
     public  void  run() {
         new  MyPrint().print(i, threadNum, fileName);
 
     }
 
}
 
/**
  * 具体的业务操作
  * */
class  MyPrint {
     private  BufferedWriter writer;
 
     public  void  print( int  x,  int  threadNum, String fileName) {
 
         try  {
             writer =  new  BufferedWriter(
                     new  FileWriter( new  File(fileName),  true ));   //如果文件已存在则在后面追加
 
             for  ( int  i = x; i <=  10000 ; i = i + threadNum) {
                 String temp = Thread.currentThread().getName() +  ": "  + i
                         "----------------------------------我是一条华丽的小尾巴" ;
 
//              System.out.println(temp);
                 writer.write(temp);
                 writer.newLine();
                 writer.flush();
             }
             writer.close();
 
         catch  (IOException e) {
             e.printStackTrace();
         }
 
     }
 
}

经过测试发现,虽然只用了5个线程,但是执行效率也是非常高的,1~2ms就可以全部处理完了。


附:

对于同样的写入信息,单线程的代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package  thread;
 
import  java.io.BufferedWriter;
import  java.io.File;
import  java.io.FileWriter;
import  java.io.IOException;
 
public  class  Test {
 
     public  static  void  main(String[] args) {
         long  millis1 = System.currentTimeMillis();
         String fileName =  "C:\\Users\\Administrator\\Desktop\\测试0.txt" // 文件名
         try  {
             BufferedWriter writer =  new  BufferedWriter(
                     new  FileWriter( new  File(fileName),  true ));
             
             for ( int  i= 0 ;i<= 100000 ;i++){
                 String temp =  "单线程: "  + i
                         "----------------------------------我是一条华丽的小尾巴" ;
                 writer.write(temp);
                 writer.newLine();
                 writer.flush();
             }
             writer.close();
         catch  (IOException e) {      
             e.printStackTrace();
        
         
         long  millis2 = System.currentTimeMillis();
         System.out.println(millis2 - millis1);   //大约162-168ms
     }
 
}

经过测试,全部执行完大概需要花费160多毫秒,这个效率跟上面的多线程比起来是远远不如的O(∩_∩)O~



本文转自 pangfc 51CTO博客,原文链接:http://blog.51cto.com/983836259/1722422,如需转载请自行联系原作者

相关文章
|
11天前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
34 1
|
3月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
40 3
|
3月前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
28 2
|
3月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
44 2
|
3月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
49 1
|
3月前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
57 1
|
2月前
|
数据采集 Java Python
爬取小说资源的Python实践:从单线程到多线程的效率飞跃
本文介绍了一种使用Python从笔趣阁网站爬取小说内容的方法,并通过引入多线程技术大幅提高了下载效率。文章首先概述了环境准备,包括所需安装的库,然后详细描述了爬虫程序的设计与实现过程,包括发送HTTP请求、解析HTML文档、提取章节链接及多线程下载等步骤。最后,强调了性能优化的重要性,并提醒读者遵守相关法律法规。
69 0
|
3月前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
62 1
|
3月前
|
Java
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件成立时被唤醒,从而有效解决数据一致性和同步问题。本文通过对比其他通信机制,展示了 `wait()` 和 `notify()` 的优势,并通过生产者-消费者模型的示例代码,详细说明了其使用方法和重要性。
45 1
|
3月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
97 6