线程总结(1)

1.什么是线程? 
   每个java都至少有一个线程---主程序当一个java程序启动时。JVM会创建主线程,并在线程中调用主程序的main()方法。
  线程可以理解为“程序内部一个独立运行单位”。
  在接触线程之前我们学过的都是单线程。
  单线程,程序运行时的调用模式是:顺序调用。
如下
   public void a(){
     b();
     c();
}
    public void b(){
     d();
}
    public void d(){}
    public void c(){}

只有当一个方法执行完下一个方法才能被执行,这个就是单线程的特点。
而多线程模型是将代码方法一个独立的运行单元中即线程中,让多个调用并行被执行。

2.线程和进程的区别
  (1)简单来说一个进程就是一个应用程序,而线程是一个进程中多个独立运行单位。
  (2)多个进程的内部数据和状态是完全独立的,而一个进程中的多个线程是共享一块内存空间和一组系统资源的,在程序内部可以互相调用,而进程间的通信大多都要通过网络实现。如我们访问google,就是我们自己机器上的IE进程和google的web服务器进程之间的通信。
  (3)线程本身的数据一般寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要
小。

3.实现多线程的三个常用方法
(1)继承Thread类
(2)实现Runable接口
(3)以匿名内部内的方式创建线程
下面以统计某磁盘文件总数为例子介绍线程。
创建统计文件的线程类
/**
 * 计算某个目录下文件的个数类
 * 该类继承Thread线程类
 *
 */
public class CountFile extends Thread{
	private String path;//声明目录路径属性
	/**
	 * 定义构造方法
	 * @param path要统计的目录路径
	 */
	public CountFile(String path){
		this.path=path;
	}
	/**
	 * 定义统计文件个数的方法
	 * @param path要统计的目录路径
	 * @return返回文件个数
	 */
	private int count(String path){
		//声明计数变量
		int count=0;
		File file=new File(path);
		//判断该文件是否存在
		if(file.exists()){
			//如果存在的话,再判断是目录还是文件,是目录的话,获取该目录下文件,然后递归
			if(file.isDirectory()){
				File [] files=file.listFiles();
				//判断files是否为空
				if(files==null){
					return count;
				}else{
					//遍历该目录下的文件
					for(int i=0;i<files.length;i++){
						count+=count(files[i].getAbsolutePath());
					}
				}
			}else if(file.isFile()){
				//如果是文件count累加1
				count++;
			}
		}else{
			return count;
		}
		return count;
	}
	/**
	 * 重写父类中run()方法
	 */
	public void run(){
		//定义开始计数的时间
		long startime=System.currentTimeMillis();
		//调用统计的方法
		int count=count(path);
		//定义结束计数时的时间
		long endtime=System.currentTimeMillis();
		System.out.println("磁盘"+path+"共有文件"+count+"个,用时"+(endtime-startime)/1000+"s");
	}
}


在主函数中实例化该线程对象并启动线程
/**
 * 线程测试类
 * 
 *
 */
public class ThreadTest {

	/**
	 * 主函数
	 */
	public static void main(String[] args) {
		//获取系统根目录
		File [] files=File.listRoots();
		//遍历数组,统计各个根目录下的文件总数
		for(int i=0;i<files.length;i++){
			//实例化线程对象
			CountFile cf=new CountFile(files[i].getAbsolutePath());
			//启动线程
			cf.start();
		}
             System.out.println(files.length+"个线程已经启动");
	}

}


运行结果如下
5个线程已经启动
磁盘G:\共有文件0个,用时0s
磁盘F:\共有文件2397个,用时0s
磁盘E:\共有文件4789个,用时0s
磁盘D:\共有文件14042个,用时1s
磁盘C:\共有文件86228个,用时18s

  我们可以看出输出语句“5个线程已经启动”是放在最后面的但他最先输出,其实主函数也是一个线程,线程并不是同时运行,而是隔着非常短的时间间隔,一个运行一会在隔一段时间另一个运行,这个时间间隔是非常短的,我们是无法感觉到这个时间间隔的,所以在这写输出语句中哪一个先运行完就那个先输出。所以也就出现了以上的结果。

上面介绍了继承Thread类来实现多线程,另外的还可以实现Runnable接口来实现,其他都一样。
还有一个就是一匿名内部类的形式创建。
如下:
public void Mythread_count(final String path){
		Thread thread=new Thread(){
			public void run() {
				System.out.println("++++++++++");
				//调用统计文件个数的方法
				int count=count(path);
				System.out.println("磁盘"+path+"共有"+count+"个"+"文件");
			}};
			//启动线程
		thread.start();
	}

这样也能实现多线程。

猜你喜欢

转载自lixiongzhi-m.iteye.com/blog/1616868