java多线程
一、
进程:
进程是程序的一次动态执行过程,经历从代码加载、代码执行到执行完毕的一个完整过程。一个应用程序就是一个进程。多进程操作系统能同时运行多个进程(程序),由于CPU具备分时机制,所以每个进程都能循环获得自己的CPU时间片。
线程:
每个Java程序都至少有一个线程——主线程。当一个Java程序启动时,JVM会创建主线程,并且在该线程中调用程序的main()方法。
1、单线程:
之前接触的都是单线程程序,单线程的特点是,被调用的方法执行完毕后当前方法才可能完成,前一个方法完成后才进行下一个方法。这是一种顺序调用。
2、多线程:
当程序同时用多个线程调用不同方法时,并不是像单线程一样的顺序调用,而是启动独立的线程之后立刻返回,各线程运行从run()方法开始,当run()结束后线程运行结束。
3、线程的优点——并行、省时。
单核CPU是通过暂停与切换实现多线程的。
进程与线程的区别:
(1)一个应用程序就是一个进程,而线程是一个进程内部的多个运行单位。
(2)多进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源(在同一进程内),在程序内部可以相互调用。
(3)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担小。
二、
每个线程对象都继承了java.lang包中的Thread类,或implements了Runnable接口类。
线程的启动:start()方法;
线程的运行:run()方法。
java多线程的实现
1、继承Thread类实现线程。重写Thread类的run()方法
public class ThreadDemo extends Thread{ //要统计的磁盘路径 private String path; //构造方法 public ThreadDemo(String path){ this.path = path; } //主方法 public static void main(String[] args){ //得到根目录 File[] root = File.listRoots(); for(int i=0;i<root.length;i++){ //创建线程对象 ThreadDemo td = new ThreadDemo(root[i].getAbsolutePath()); td.start(); } } //重写run方法 public void run(){ long start = System.currentTimeMillis(); System.out.println("开始时间:"+start); int num = countFile(path); long end = System.currentTimeMillis(); System.out.println("结束时间:"+end); System.out.println(path+"统计共有"+num+"个文件!"); } //统计文件数目的方法 public int countFile(String path){ int count = 0; File file = new File(path); //得到该目录下的所有文件 File[] subFile = file.listFiles(); //如果该目录为空或 if(null==subFile||subFile.length==0){ return count; } for(int i=0;i<subFile.length;i++){ if(subFile[i].isDirectory()){ count+=countFile(subFile[i].getAbsolutePath()); }else if(subFile[i].isFile()){ count++; } } return count; } }
2、实现Runnable接口创建线程
Runnable接口只有一个run()方法没有start()方法,所以在使用Runnable接口的实现类创建线程时,启动线程要构造一个Thread对象,并调用它的start()方法来启动线程。
3、使用匿名内部类创建线程
在实例化Runnable方法时使用匿名内部类重写run()方法。然后再用Thread对象的start()方法启动线程。
如果run()方法要用到while(true){....}时,会发现CPU的占用率是100%。这时就要让线程隔一段时间暂停一下。在线程运行时,调用一个静态方法sleep(long time),可以让线程暂停time时间后再开始运行,暂停的时间以毫秒计。Thread.sleep(long time)只会让线程暂停(挂起),不是停止也不是退出。当线程在sleep时如果JVM或其他线程强行终止这个线程,sleep方法会抛出线程中断异常InterruptedException,所以需要处理。