进程是程序的一次动态执行过程,它须要经历从代码加载,代码执行到执行完毕的一个完整的过程,这个过程也是进程自己从产生,发展到最终消亡的过程。多进程操做系统能同时达运行多个进程(程序),因为CPU具有分时机制,因此每一个进程都能循环得到本身的CPU时间片。因为CPU执行速度很是快,使得全部程序好像是在同时运行同样。java
多线程是实现并发机制的一种有效手段。进程和线程同样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是进程的基础之上进行进一步的划分。所谓多线程是指一个进程在执行过程当中能够产生多个更小的程序单元,这些更小的单元称为线程,这些线程能够同时存在,同时运行,一个进程可能包含多个同时执行的线程。进程与线程的区别如图所示:多线程
在Java中实现多线程有两种手段,一种是继承Thread类,另外一种就是实现Runnable接口。下面咱们就分别来介绍这两种方式的使用。并发
public class ThreadDemo { public static void main(String[] args) { MyThread threadA=new MyThread("线程A"); MyThread threadB=new MyThread("线程B"); Thread t1=new Thread(threadA); Thread t2=new Thread(threadB); t1.start(); t2.start(); } } class MyThread implements Runnable{ private String name; int i=0; public MyThread(String name) { this.name = name; } @Override public void run() { while(i<10){ System.out.println(name+" i:"+i); i++; } } }
运行结果ide
线程A i:0 线程B i:0 线程A i:1 线程B i:1 线程A i:2 线程B i:2 线程A i:3 线程B i:3 线程A i:4 线程B i:4 线程A i:5 线程B i:5 线程A i:6 线程B i:6 线程B i:7 线程A i:7 线程A i:8 线程A i:9 线程B i:8 线程B i:9
public class ThreadDemo { public static void main(String[] args) { MyThread threadA=new MyThread("线程A"); MyThread threadB=new MyThread("线程B"); Thread t1=new Thread(threadA); Thread t2=new Thread(threadB); t1.start(); t2.start(); } } class MyThread extends Thread{ private String name; int i=0; public MyThread(String name) { this.name = name; } @Override public void run() { while(i<10){ System.out.println(name+" i:"+i); i++; } } }
运行结果this
线程B i:0 线程B i:1 线程B i:2 线程B i:3 线程B i:4 线程B i:5 线程B i:6 线程B i:7 线程B i:8 线程B i:9 线程A i:0 线程A i:1 线程A i:2 线程A i:3 线程A i:4 线程A i:5 线程A i:6 线程A i:7 线程A i:8 线程A i:9
两个线程,哪一个线程抢到了CPU执行权,就执行那个线程。线程调用start()方法,实际上执行的是run()方法体中的主体。spa
public class Thread extends Object implements Runnable操作系统
从Thread类的定义能够清楚的发现,Thread类也是Runnable接口的子类,但在Thread类中并无彻底实现Runnable接口中的run()方法,下面是Thread类的部分定义。.net
Private Runnable target; public Thread(Runnable target,String name){ init(null,target,name,0); } private void init(ThreadGroup g,Runnable target,String name,long stackSize){ ... this.target=target; } public void run(){ if(target!=null){ target.run(); } }
从定义中能够发现,在Thread类中的run()方法调用的是Runnable接口中的run()方法,也就是说此方法是由Runnable子类完成的,因此若是要经过继承Thread类实现多线程,则必须覆写run()。线程
实际上Thread类和Runnable接口之间在使用上也是有区别的,若是一个类继承Thread类,则不适合于多个线程共享资源,而实现了Runnable接口,就能够方便的实现资源的共享。code
要想实现多线程,必须在主线程中建立新的线程对象。任何线程通常具备5种状态,即建立,就绪,运行,阻塞,终止。下面分别介绍一下这几种状态
建立状态
在程序中用构造方法建立了一个线程对象后,新的线程对象便处于新建状态,此时它已经有了相应的内存空间和其余资源,但还处于不可运行状态。新建一个线程对象可采用Thread类的构造方法来实现,例如“Thread thread=new Thread()”。
就绪状态
新建线程对象后,调用该线程的start()方法就能够启动线程。当线程启动时,线程进入就绪状态。此时,线程将进入线程队列排队,等待CPU服务,这代表它已经具有了运行条件。
运行状态
当就绪状态被调用并得到处理器资源时,线程就进入了运行状态。此时,自动调用该线程对象的run()方法。run()方法定义该线程的操做和功能。
阻塞状态
一个正在执行的线程在某些特殊状况下,如被人为挂起或须要执行耗时的输入/输出操做,会让CPU暂时停止本身的执行,进入阻塞状态。在可执行状态下,若是调用sleep(),suspend(),wait()等方法,线程都将进入阻塞状态,发生阻塞时线程不能进入排队队列,只有当引发阻塞的缘由被消除后,线程才能够转入就绪状态。
死亡状态
线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具备继续运行的能力。
Java程序每次运行至少启动几个线程?
回答:至少启动两个线程,每当使用Java命令执行一个类时,实际上都会启动一个JVM,每个JVM实际上就是在操做系统中启动一个线程,Java自己具有了垃圾的收集机制。因此在Java运行时至少会启动两个线程,一个是main线程,另一个是垃圾收集线程。
public class ThreadDemo { public static void main(String[] args) { MyThread myThread=new MyThread(); new Thread(myThread,"线程A").start(); new Thread(myThread,"线程B").start(); } } class MyThread implements Runnable{ public void run() { for (int i = 0; i <3 ; i++) { System.out.println("当前线程名称:"+Thread.currentThread().getName()); } } }