单线程也就是程序执行时,所跑的程序路径(处理的东西)是连续顺序下来的,必须前面的处理好,后面的才会执行到。
多线程嘛,举个例子也就是说程序可以同时执行2个以上相同类似的操作,比如一些搜索代理或者群发email的多线程软件,由于操作一次需要网络的返回信息 花的时间比较长,而对cpu来说却是空闲的,如果是一个一个顺序执行,那么搜索几千个IP就会花上好久好久。而如果用多线程就可以在等待期间加入其他的搜索,然后等待,这样可以提高效率。不过多线程和多进程公用一些资源时要考虑的问题好像也是一样的,,对于一些公共资源或者公共变量的访问和修改时要注意特别的,需要一些锁定什么的,还有顺序问题的考虑。
多线程编程的目的,就是"最大限度地利用CPU资源",当某一线程的处理不需要占用CPU而只和I/O,OEMBIOS等资源打交道时,让需要占用CPU资源的其它线程有机会获得CPU资源。也就是说当CPU资源已经被用得差不多了,再增加线程也无济于事么。
实例:单线程,多线程的一个应用实例:
单线程的思路是遍历所有文件,当遍历到文件是 .java的时候,查找这个文件的内容,查找完毕之后,再遍历下一个文件
现在通过多线程调整这个思路:
遍历所有文件,当遍历到文件是.java的时候,创建一个线程去查找这个文件的内容,不必等待这个线程结束,继续遍历下一个文件
先看单线程:
package Stream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class OnetThreadFindFileString {
/**
* @param file 查找的目录
* @param search 查找的字符串
*/
public static void search(File file, String search) {
if (file.isFile()) {
if(file.getName().toLowerCase().endsWith(".java")){
String fileContent = readFileConent(file);
if(fileContent.contains(search)){
System.out.printf("找到子目标字符串%s,在文件:%s%n",search,file);
}
}
}
if (file.isDirectory()) {
File[] fs = file.listFiles();
for (File f : fs) {
search(f, search);
}
}
}
/**
* @param file 文件名
* @return 文件内容
*/
public static String readFileConent(File file){
try (FileReader fr = new FileReader(file)) {
char[] all = new char[(int) file.length()];
fr.read(all);
return new String(all);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
File folder =new File("e:\\project");
search(folder,"out");
long end = System.currentTimeMillis();
System.out.println("花费时间为:"+(end-start)+"毫秒");
}
}
运行结果:
找到子目标字符串out,在文件:e:\project\hellogit\src\hellogit\HelloGit.java
找到子目标字符串out,在文件:e:\project\spring\src\com\how2java\service\ProductService.java
找到子目标字符串out,在文件:e:\project\spring\src\com\how2java\aspect\LoggerAspect.java
找到子目标字符串out,在文件:e:\project\mybatis\src\com\how2java\TestMybatis.java
找到子目标字符串out,在文件:e:\project\j2se\src\HelloWorld.java
找到子目标字符串out,在文件:e:\project\helloworld\src\helloworld\HelloWorld.java
找到子目标字符串out,在文件:e:\project\struts\src\com\how2java\action\UploadAction.java
找到子目标字符串out,在文件:e:\project\tmall\src\com\how2java\tmall\test\TestTmall.java
花费时间为:196毫秒
多线程(继承Thread类)
package Stream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class FindStringThread extends Thread{
private File file;
private String search;
public FindStringThread(File file,String search){
this.file=file;
this.search=search;
}
public void run(){
String fileContent = readFileConent(file);
if(fileContent.contains(search)){
System.out.printf("找到子目标字符串%s,在文件:%s%n",search,file);
}
}
public static String readFileConent(File file){
try (FileReader fr = new FileReader(file)) {
char[] all = new char[(int) file.length()];
fr.read(all);
return new String(all);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
测试类:
package Stream;
import java.io.File;
public class MulThreadFindFileString {
public static void search(File file, String search) {
if (file.isFile()) {
if(file.getName().toLowerCase().endsWith(".java")){
new FindStringThread(file,search).start();
}
}
if (file.isDirectory()) {
File[] fs = file.listFiles();
for (File f : fs) {
search(f, search);
}
}
}
public static void main(String[] args){
long start = System.currentTimeMillis();
File folder =new File("e:\\project");
search(folder,"out");
long end = System.currentTimeMillis();
System.out.println("花费时间为:"+(end-start)+"毫秒");
}
}
运行结果:
找到子目标字符串out,在文件:e:\project\hellogit\src\hellogit\HelloGit.java
找到子目标字符串out,在文件:e:\project\spring\src\com\how2java\service\ProductService.java
找到子目标字符串out,在文件:e:\project\spring\src\com\how2java\aspect\LoggerAspect.java
找到子目标字符串out,在文件:e:\project\mybatis\src\com\how2java\TestMybatis.java
找到子目标字符串out,在文件:e:\project\j2se\src\HelloWorld.java
找到子目标字符串out,在文件:e:\project\helloworld\src\helloworld\HelloWorld.java
找到子目标字符串out,在文件:e:\project\struts\src\com\how2java\action\UploadAction.java
找到子目标字符串out,在文件:e:\project\tmall\src\com\how2java\tmall\test\TestTmall.java
花费时间为:160毫秒
可见在这次(多次运行均是多线程优于单线程)实验中,多线程查找指定文件以及该文件下子文件的指定内容,性能优于单线程。